说我有这个物理结构:
/
+-- conflicttest
| +-- A.cpp
| +-- A.h
| +-- main.cpp
+-- libconflict
| +-- conflict
| | +-- A.h
| | +-- B.h
| +-- A.cpp
| +-- B.cpp
这些是libconflict的根源,请深呼吸:
libconflict中的
class B
header :// libconflict B.h
class B
{
public:
void bar();
protected:
int j_;
};
libconflict中的
class B
实现:// libconflict B.cpp
#include "conflict/B.h"
void B::bar()
{
std::cout << "B::bar" << std::endl;
}
libconflict中的
class A
header :// libconflict A.h
# include "conflict/B.h"
class A : public B
{
public:
A();
private:
int i_;
};
libconflict中的
class A
实现:#include "conflict/A.h"
A::A()
{
std::cout << "libconflict A is alive" << std::endl;
i_ = 51; // some random fields and values... I should admit I am lost
j_ = 47;
}
现在,冲突测试的来源已经结束:
冲突测试中的
class A
header :// conflicttest A.h
class A
{
public:
A();
void foo();
};
冲突测试中的
class A
实现:// conflicttest A.cpp
#include "A.h"
A::A()
{
std::cout << "A is alive" << std::endl;
}
void A::foo()
{
std::cout << "A::foo" << std::endl;
}
最后,
main.cpp
:// main.cpp in conflicttest
#include "conflict/A.h"
int main()
{
B* b = new A;
b->bar();
return 0;
}
......我正在使用Visual Studio 2010构建此解决方案。
conflicttest
是与静态库libconflict
链接的可执行文件。这样编译就像一个咒语,但是,不管您相信与否,输出为:
A is alive
B::bar
链接器实际上使用
A
中的符号conflicttest
,它绝对不是B
,更糟糕的是,它可以调用B::bar()
。我迷路了,编译器为什么不提示?
最佳答案
您违反了One Definition Rule。
编译器没有提示,因为它在跨越翻译单元边界时可以检测到的东西有限。