C ++链接器 - 缺少重复的符号 [英] C++ linker - Lack of duplicate symbols
问题描述
为什么下面的代码不会给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的Impl :: Impl()
Bar.cpp的Impl :: Impl()
< == main()
以下命令:
g ++ -o a.out main.cpp Foo.cpp Bar.cpp
结果如下:
==> main()
Foo.cpp的Impl :: Impl()
Foo.cpp的Impl :: Impl()
< == main()
我已经用gcc 4.1.2,Visual Studio 2008和Green Hills Multi 4.2.4尝试过了,它们都产生相同的结果。 p>
Foo.h
#ifndef FOO_H
struct Impl;
class Bar;
class Foo
{
public:
Foo();
〜Foo();
私人:
Impl * p;
Bar * bar;
};
#endif
Foo.cpp
#include< iostream>
#includeFoo.h
#includeBar.h
struct Impl
{
Impl()
{
std :: cout<< Foo.cpp的Impl :: Impl()<<的std :: ENDL;
}
};
Foo :: Foo()
:p(新Impl),
bar(新酒吧)
{
}
Foo ::〜Foo()
{
delete p;
删除栏;
Bar.h
#ifndef BAR_H
#define BAR_H
struct Impl;
class Bar
{
public:
Bar();
〜Bar();
私人:
Impl * p;
};
#endif
Bar.cpp
#include< iostream>
#includeBar.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>
#includeFoo.h
int main(int argc,char const * argv [])
{
std :: cout<< ==> main()<<的std :: ENDL;
Foo * f = new Foo();
std :: cout<< < == main()<<的std :: ENDL;
返回0;
解决方案a href =http://en.wikipedia.org/wiki/One_Definition_Rule =nofollow noreferrer>一个定义规则,编译器/链接器不需要告诉你。 p>
Why does the following code not give me a duplicate symbol linker error for Impl?
I ran across this problem in some code I inherited and I'm recreating a shorter version here for simplicity.
I have two classes, Foo and Bar, that each define a different version of the same struct (Impl) in each of their .cpp files. So Foo.cpp and Bar.cpp each have an identically named Impl definition, but each one has a different inline constructor implementation.
Both Foo and Bar have a member variable of type Impl and each forward declares Impl in its .h file.
Foo.cpp news an instance of Bar inside its constructor. What's interesting is what gets created depends on the order the files are linked.
So this compilation command:
g++ -o a.out main.cpp Bar.cpp Foo.cpp
results in this output:
==> main() Bar.cpp's Impl::Impl() Bar.cpp's Impl::Impl() <== main()
And this command:
g++ -o a.out main.cpp Foo.cpp Bar.cpp
results in this output:
==> main() Foo.cpp's Impl::Impl() Foo.cpp's Impl::Impl() <== main()
I have tried this with gcc 4.1.2, Visual Studio 2008 and the Green Hills Multi 4.2.4 and they all produce the same result.
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; }
解决方案You're violating the one definition rule, and the compiler/linker isn't required to tell you about it.
这篇关于C ++链接器 - 缺少重复的符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!