C++的multiple definition of *** first defined here错误

http://yumaoshu.com/?p=235

C++的multiple definition of *** first defined here错误

这两天写程序碰到个问题。那么久那么久终于解决了,其实很简单点问题。但既然付出了这么长时间,就让我永远记住它吧。。写篇日志(前面有两篇写了一半的大家说的那种垃圾流水账文,都没发……这里闲置好久好久了)

首先我把出现这个现象的情况简化。我专门写了个测试程序,共有如下几个文件

 

myClass.hmyClass1.hmyClass1.cppmain.cpp
myClass.hmyClass1.h
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef _MYCLASS_H_
#define _MYCLASS_H_
 
#include <iostream>
 
class myClass
{
public :
     int print();
};
 
int myClass::print()
{
     std::cout << "YuMS" << "\n" ;
     return 0;
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef _MYCLASS1_H_
#define _MYCLASS1_H_
 
#include "myClass.h"
#include <iostream>
 
class myClass1
{
public :
     myClass myclass;
     int print();
};
 
#endif
myClass1.cppmain.cpp
?
1
2
3
4
5
6
7
8
#include <iostream>
#include "myClass1.h"
 
int myClass1::print()
{
     myclass.print();
     return 0;
}
?
1
2
3
4
5
6
7
8
#include "myClass1.h"
 
int main()
{
     myClass1 myclass1;
     myclass1.print();
     return 0;
}

使用g++进行生成

?
1
g++ -o main.exe main.cpp myClass1.cpp

得到的结果是

?
1
2
3
4
5
6
C:\Users\YuMS\AppData\Local\Temp\ccU3jb7q.o:myClass1.cpp:(.text+0x0): multiple d
efinition of `myClass::print()'
C:\Users\YuMS\AppData\Local\Temp\ccldoy68.o:main.cpp:(.text+0x0): first defined
here
collect2: ld returned 1 exit status
shell returned 1

大约分析一下,原因从我这种弱爆了的人嘴里说出来大约应该是

main.cpp和myClass1.cpp都include了myClass1.h

虽然myClass1.h有include保护,但也招架不了分别编译

所以链接的时候导致无辜的myClass.h挂掉了

 

注意到了么?!

是myClass.h挂掉了,不是myClass1.h。

myClass.h其实是不无辜的,它的写法太2了。把该写在本应有的myClass.cpp中的print函数的实现写在了自己的外面。

 

为什么我会写出这么2的程序呢?那是因为在用到template的类中只能这样写。我就认为在一般的程序里显然也能这样,就那么一个函数,写个cpp不爽。

于是触发了大boss,费了我这么长时间。

事实上

“模板定义很特殊。由template <…> 处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知。在编译器和连接器的某一处,有一机制能去掉指定模板 的多重定义。所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义。”《C++编程思想》

template的只能这样(或用export,本文不作讨论),而这个不能……

 

解决方法是:分开写,如下

myClass.hmyClass.cppmyClass1.hmyClass1.cppmain.cpp
myClass.hmyClass1.h
?
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef _MYCLASS_H_
#define _MYCLASS_H_
 
#include <iostream>
 
class myClass
{
public :
     int print();
};
 
#endif
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef _MYCLASS1_H_
#define _MYCLASS1_H_
 
#include "myClass.h"
#include <iostream>
 
class myClass1
{
public :
     myClass myclass;
     int print();
};
 
#endif
myClass1.cppmain.cpp
?
1
2
3
4
5
6
7
8
#include <iostream>
#include "myClass1.h"
 
int myClass1::print()
{
     myclass.print();
     return 0;
}
?
1
2
3
4
5
6
7
#include "myClass1.h"
int main()
{
     myClass1 myclass1;
     myclass1.print();
     return 0;
}
myClass.cpp 
?
1
2
3
4
5
6
7
8
#include <iostream>
#include "myClass.h"
 
int myClass::print()
{
     std::cout << "YuMS" << "\n" ;
     return 0;
}
 

使用g++进行生成

?
1
g++ -o main.exe main.cpp myClass.h myClass1.cpp

另附程序(若将myClass.h故意写成模版就没事了……好玩)

myClass.hmyClass1.hmyClass1.cppmain.cpp
myClass.hmyClass1.h
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef _MYCLASS_H_
#define _MYCLASS_H_
 
#include <iostream>
 
template < class T>
class myClass
{
public :
     int print();
};
 
template < class T>
int myClass<T>::print()
{
     std::cout << "YuMS" << "\n" ;
     return 0;
}
 
#endif
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef _MYCLASS 1 _H_
#def ine _MYCLASS 1 _H_
 
#include "myClass.h"
#include <iostream>
 
class myClass 1
{
public:
     myClass<int> myclass;
     int print ();
};
 
#endif
myClass1.cppmain.cpp
?
1
2
3
4
5
6
7
8
#include <iostream>
#include "myClass1.h"
 
int myClass1::print()
{
     myclass.print();
     return 0;
}
?
1
2
3
4
5
6
7
8
#include "myClass1.h"
 
int main()
{
     myClass1 myclass1;
     myclass1.print();
     return 0;
}

使用g++进行生成

?
1
g++ -o main.exe main.cpp myClass1.cpp

 

 

转载于:https://www.cnblogs.com/Adrian99/p/3145762.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值