说我有这个物理结构:

/
  +-- 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

编译器没有提示,因为它在跨越翻译单元边界时可以检测到的东西有限。

08-26 13:31