C ++链接器 - 缺少重复的符号 [英] C++ linker - Lack of duplicate symbols

查看:119
本文介绍了C ++链接器 - 缺少重复的符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么下面的代码不会给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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆