I might be a bit late for answering the question the OP made but since I think the answer is not fully clear, I would like to help future readers.
Lets try a test... compile the following files:
//main.cpp
#include <iostream>
#include "test.hpp"
class Test {
public:
void talk() {
std::cout<<"I'm test MAIN\n";
}
};
int main()
{
Test t;
t.talk();
testfunc();
}
//test.hpp
void testfunc();
//test.cpp
#include <iostream>
class Test {
public:
void talk()
{
std::cout<<"I'm test 2\n";
}
};
void testfunc() {
Test t;
t.talk();
}
Now run the executable.
You would expect to see:
I'm test MAIN
I'm test 2
What you should see thought is:
I'm test MAIN
I'm test MAIN
What happened?!?!!
Now try putting an unnamed namespace around the "Test" class in "test.cpp" like so:
#include <iostream>
#include "test.hpp"
namespace{
class Test {
public:
void talk()
{
std::cout<<"I'm test 2\n";
}
};
}
void testfunc() {
Test t;
t.talk();
}
Compile it again and run.
The output should be:
I'm test MAIN
I'm test 2
Wow! It works!
As it turns out, it is important to define classes inside unnamed namespaces so that you get the proper functionality out of them when two class names in different translation units are identical.
Now as to why that is the case, I haven't done any research on it (maybe someone could help here?) and so I can't really tell you for sure. I'm answering purely from a practical standpoint.
What I would suspect though is that, while it is true that C structs are indeed local to a translation unit, they are a bit different from classes since classes in c++ usually have behavior assigned to them. Behavior means functions and as we know, functions are not local to the translation unit.
This is just my assumption.