Say I have two different cpp files. Both declare classes with the same name, but perhaps a totally different structure (or perhaps the same structure, different implementation). The classes do not appear in the header files. (As an example, suppose they are Node classes for different list classes.)
I've seen these classes conflict. Is this expected by the standard? What solutions are there to this problem?
UPDATE:
As suggested by answers/comments, anonymous namespaces are what I was looking for.
The standard way around this problem is to wrap the classes in different namespaces.
It violates One Definition Rule. It's hard for compiler to detect the error, because they are in different compilation units. And even linker cannot detect all errors.
See an example in http://www.cplusplus.com/forum/general/32010/ . My compiler and linker (g++ 4.2.1) can build the final executable without any error, but the output is wrong.
If I change the example a bit, I get segmentation fault.
// main.cpp
#include <iostream>
#include <list>
using namespace std;
struct Handler
{
Handler() : d(10, 1.234) {}
list<double> d;
};
extern void test_func();
int main(void)
{
Handler h;
cout << h.d.back() << endl;
test_func();
return 0;
}
// test.cpp
#include <iostream>
#include <string>
using namespace std;
struct Handler
{
Handler() : d("test Handler") {}
string d;
};
void test_func()
{
Handler h;
cout << h.d << endl;
}
It's recommended to differentiate you class by namespace. For example of Node, you can use nest class and define the Node in the parent list class. Or you can add you class in anonymous namespace. See How can a type that is used only in one compilation unit, violate the One Definition Rule?
You can use namespace to have multiple classes with same name by sub-scoping them in different namespaces. See: http://www.cplusplus.com/doc/tutorial/namespaces/
I'm not sure if I'm missing some detail here, but you wrap each class in a namespace
.
namespace A {
class Node { };
}
namespace B {
class Node { };
}
Then you can use A::Node
or B::Node
.
I've seen these classes conflict. Is this expected by the standard?
The standard says you can't do that. It would violate the one definition rule. (How to fix this has already been covered in other answers)