【发布时间】:2010-12-17 03:50:03
【问题描述】:
为什么下面的代码没有给出 Impl 的重复符号链接器错误?
我在继承的一些代码中遇到了这个问题,为了简单起见,我在这里重新创建了一个较短的版本。
我有两个类,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;
}
【问题讨论】:
标签: c++ visual-studio gcc linker