Is it possible to avoid repeating the class name i

2020-01-25 11:38发布

问题:

Is there a way to avoid the Graph:: repetition in the implementation file, yet still split the class into header + implementation? Such as in:

Header File:

#ifndef Graph_H
#define Graph_H

class Graph {
public:
    Graph(int n);
    void printGraph();
    void addEdge();
    void removeEdge();
};

#endif

Implementation File:

Graph::Graph(int n){}
void Graph::printGraph(){}
void Graph::addEdge(){}
void Graph::removeEdge(){}

回答1:

I'm guessing this is to avoid lots of "unnecessary typing". Sadly there's no way to get rid of the scope (as many other answers have told you) however what I do personally is get the class defined with all my function prototypes in nice rows, then copy/paste into the implementation file then ctrl-c your ClassName:: on the clip board and run up the line with ctrl-v.



回答2:

If you want to avoid typing the "Graph::" in front of the printGraph, addEdge etc., then the answer is "no", unfortunately. The "partial class" feature similar to C# is not accessible in C++ and the name of any class (like "Graph") is not a namespace, it's a scope.



回答3:

No there's not. Not directly at least. You could go for preprocessor tricks, but don't do it.

#define IMPL Graph::

IMPL Graph(int n){}
void IMPL printGraph(){}
void IMPL addEdge(){}
void IMPL removeEdge(){}

Also, you shouldn't even want to do it. What's the point. Besides it being a C++ rule, it lets you know you're actually implementing a member function.



回答4:

No, there is no way to avoid it. Otherwise, how would you know if a given function definition is for a class function or for a static function?



回答5:

If you are asking if you can define a member function such as Graph::printGraph without specifying the class name qualification, then the answer is no, not the way that you want. This is not possible in C++:

implementation file:

void printEdge(){};

The above will compile just fine, but it won't do what you want. It won't define the member function by the same name within the Graph class. Rather, it will declare and define a new free function called printEdge.

This is good and proper, if by your point of view a bit of a pain, because you just might want two functions with the same name but in different scopes. Consider:

// Header File
class A
{
  void foo();
};

class B
{
  void foo();
};

void foo();

// Implementation File
void foo()
{
}

Which scope should the definition apply to? C++ does not restrict you from having different functions with the same names in different scopes, so you have to tell the compiler what function you're defining.



回答6:

        //yes it is possible using preprocessor like this:

        #define $ ClassName //in .cpp 

    void $::Method1() 
    { 
    } 

    //or like this: in the header .h:

        #undef $
        #define $ ClassName' 

// but you have to include the class header in last #include in your .cpp:

        #include "truc.h"
        #include "bidule.h" ...
        #include "classname.h" 

        void $::Method() { }  

        //i was using also 
        #define $$ BaseClass 
        //with single inheritance  than i can do this: 

        void $::Method() 
        { 
        $$::Method(); //call base class method 
        } 

        //but with a typedef defined into class like this it's better to do this: 
        class Derived : Base 
        { 
        typedef Base $$;  

    }


回答7:

EDIT: I misread your question :( this would be an answer to the question whether you can split header-files. sorry

The simple answer: You can split up c++-file, but you can not split up header-files.

The reason is quite simple. Whenever your compiler needs to compile a constructor, it needs to know exactly how many memory it needs to allocate for such an object.

for example:

class Foo {
   double bar;  //8 bytes
   int goo;  //4 bytes
}

'new Foo()' would require the allocation of 12 bytes memory. But if you were allowed to extends your class definitions over multiple files (i.e. split header files), you would easily make a mess of this. Your compiler would never know if you already told it everything about the class, or whether you did not. Different places in your code could have different definitions of your class, leading to either segmentation faults or extremely cryptical compiler errors.

For example:

h1.h:

class Foo {
   double bar;  //8 bytes
   int goo;  //4 bytes
}

h2.h: #include "h1.h"

class Foo {
   double goo;  //8 bytes
}// we extend foo with a double.

foo1.cpp:

#include "foo1.h"

Foo *makeFoo() {
   return new Foo();

}

foo2.cpp:

#include "foo2.h"

void cleanupFoo(Foo *foo) {
   delete foo;
}

foo1.h:

#include "h1.h"

Foo *makeFoo();

foo2.h:

#include "h1.h"
#include "h2.h"

void cleanupFoo(Foo *foo)

main.cpp:

#include foo1.h
#include foo2.h

void main() {
    Foo *foo = makeFoo();
    cleanupFoo(foo);
}

Now very carefully check what happens if you first compile main.cpp to main.o, then foo1.cpp to foo1.o and foo2.cpp to foo2.o, and finally link all of them together. This should compile, but the makeFoo() allocates someting else then the cleanupFoo() deallocated.

So there you have it, feel free to split .cpp files, but don't split up classes over header files.



标签: c++ class syntax