为什么以下代码不会给我一个重复符号链接器错误的Impl?
我在继承的一些代码中遇到了这个问题,为简单起见,在此重新创建了一个更短的版本。
我有两个类Foo和Bar,它们分别在各自的.cpp文件中定义了相同结构体Impl的不同版本。因此,Foo.cpp和Bar.cpp都有一个相同命名的Impl定义,但每个定义都有不同的内联构造函数实现。
Foo和Bar都有一个Impl类型的成员变量,并且在其.h文件中前向声明了Impl。
Foo.cpp在其构造函数中使用Bar的一个实例。有趣的是,所创建的实例取决于文件链接的顺序。
因此,编译命令如下:
在输出中会得到以下结果:
这将导致以下输出结果:
我在继承的一些代码中遇到了这个问题,为简单起见,在此重新创建了一个更短的版本。
我有两个类Foo和Bar,它们分别在各自的.cpp文件中定义了相同结构体Impl的不同版本。因此,Foo.cpp和Bar.cpp都有一个相同命名的Impl定义,但每个定义都有不同的内联构造函数实现。
Foo和Bar都有一个Impl类型的成员变量,并且在其.h文件中前向声明了Impl。
Foo.cpp在其构造函数中使用Bar的一个实例。有趣的是,所创建的实例取决于文件链接的顺序。
因此,编译命令如下:
g++ -o a.out main.cpp Bar.cpp Foo.cpp
在输出中会得到以下结果:
==> main()
Bar.cpp's Impl::Impl()
Bar.cpp's Impl::Impl()
<== main()
而这个命令:
g++ -o a.out main.cpp Foo.cpp Bar.cpp
这将导致以下输出结果:
==> main()
Foo.cpp's Impl::Impl()
Foo.cpp's Impl::Impl()
<== main()
我已经尝试使用gcc 4.1.2、Visual Studio 2008和Green Hills Multi 4.2.4进行了测试,它们都产生了相同的结果。
Foo.h
#ifndef FOO_H
struct Impl;
class Bar;
class Foo
{
public:
Foo();
~Foo();
private:
Impl* p;
Bar* bar;
};
#endif
Foo.cpp
#include <iostream>
#include "Foo.h"
#include "Bar.h"
struct Impl
{
Impl()
{
std::cout << "Foo.cpp's Impl::Impl()" << std::endl;
}
};
Foo::Foo()
: p(new Impl),
bar(new Bar)
{
}
Foo::~Foo()
{
delete p;
delete bar;
}
Bar.h
#ifndef BAR_H
#define BAR_H
struct Impl;
class Bar
{
public:
Bar();
~Bar();
private:
Impl* p;
};
#endif
Bar.cpp
#include <iostream>
#include "Bar.h"
struct Impl
{
Impl()
{
std::cout << "Bar.cpp's Impl::Impl()" << std::endl;
}
};
Bar::Bar()
: p(new Impl)
{
}
Bar::~Bar()
{
delete p;
}
main.cpp
#include <iostream>
#include "Foo.h"
int main (int argc, char const *argv[])
{
std::cout << "==> main()" << std::endl;
Foo* f = new Foo();
std::cout << "<== main()" << std::endl;
return 0;
}