这些名称冲突如何在C ++中解决?

| 说我有这个物理结构:
/
  +-- conflicttest
  |     +-- A.cpp
  |     +-- A.h
  |     +-- main.cpp
  +-- libconflict
  |     +-- conflict
  |     |     +-- A.h
  |     |     +-- B.h
  |     +-- A.cpp
  |     +-- B.cpp
这些是libconflict的根源,请深呼吸: libconflict中的“ 1”标题:
// libconflict B.h
class B
{
public:
    void bar();
protected:
    int j_;
};
libconflict中的“ 1”实现:
// libconflict B.cpp
#include \"conflict/B.h\"

void B::bar()
{
    std::cout << \"B::bar\" << std::endl;
}
libconflict中的“ 5”标题:
// libconflict A.h
# include \"conflict/B.h\"

class A : public B
{
public:
    A();
private:
    int i_;
};
“ libconflict”中的“ 5”实现:
#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;
}
现在,冲突测试的来源已经结束: 冲突测试中的“ 5”标题:
// conflicttest A.h
class A
{
public:
    A();
    void foo();
};
冲突测试中的“ 5”实施:
// 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
链接器实际上使用来自ѭ15的符号
A
,这绝对不是ѭ20,更糟的是,它可以调用
B::bar()
。 我迷路了,编译器为什么不抱怨?     
已邀请:
        您违反了一个定义规则。 编译器没有抱怨,因为它在跨越翻译单元边界时可以检测到的东西有限。     
        我猜您实际上并没有链接到您的冲突库。但实际上,就是不要这样做。如果绝对必须使用名称空间。     
        答案很简单。您撒谎了编译器,作为回报,编译器为您撒谎。函数的内部实现使得它们仅在每个类的某个函数表中排列。当您有不同的类声明时,编译器将根据它来推导功能表,但是推导是错误的。该表中没有函数名称,因此编译器无法检测到故障情况。     
        您对A类有两种不同的定义。这违反了ODR。因此,该程序不是有效的C ++程序。不需要编译器来诊断此错误。     

要回复问题请先登录注册