头文件中写类的实现出现函数重复定义的问题
来源:互联网 发布:ubuntu 17.04 cuda8.0 编辑:程序博客网 时间:2024/06/05 22:54
先来做一个实验,你在一个头文件中定义一个类,然后把内中的一个函数的实现写在这个头文件当中。
//A_test.h
#ifndefine _A_TEST_
#define _A_TEST_
class A
{
void test();
};
void A::test()
{
}
#endif
//A_test.cpp
#include A_test.h
//B_test.cpp
#include A_test.h
//C_test.cpp
#include A_test.h
然后在两个B.cpp,C.cpp包含这个头文件,请问能否编译通过。答案是不行的,会报错,所你重复定义函数test()
但是如果你把这个函数定义到class A里面,然后编译就不报错了。
另外如果你把这个函数定义在这个头文件类的外面,但是前面加上inline,也可以通过编译。
除此之外,如果你把这个函数的实现写在另外一个包含这个头文件的cpp文件中,也可以通过编译,这也是最规范的写法。
与此对应,如果你在这个头文件中声明了一个函数,如果直接就在这个头文件中实现,那么除非你把它定义为inline 函数,不然会发生二次定义的错误,当然把一个实现放到一个对应的cpp中,自然不会报错。
在常规理解中,.h只能写声明,cpp写实现。这是很规范 。但是为什么有些库的头文件也把一些类的实现写出来了,有些函数也直接定义在那个头文件中,在很多.cpp中也不断的被包含呢,结果并不报错。举个例子来时,complex.h这个头文件在很多数值.cpp中间都要包含,如果这个头文件中有些函数写了实现,就会报错。
那么究竟如何来理解这种现象呢:
有3点:
1是编译器的唯一命名规则,就是inline函数,class和模板类函数被多次包含的情况下,在编译的时候,编译器会自动把他们认为是同一个函数,不会发生二次定义的问题。前提是他们一模一样。
2是编译器会把class里面定义的函数当做inline函数,所以直接在类里面实现函数的定义没有关系。由上面的说明,他不会发生二次定义的问题。
3一般函数的声明和实现分开,在编译的时候,声明可以无数次,但是定义只能一份,只会生成一份函数的.obj,所以有函数调用的地方,编译器必须在调用的地方先保持现场,然后在花点时间去调用函数,然后回来,恢复现场。所以函数在头文件中实现,如果被包含二次。函数的实现就被编译了2次,如果单独写在一个.cpp中间,自然就编译成为一份.obj,不会产生二义性的问题。
3.inline函数在编译的时候直接复制在有该函数的地方,在空间上有消耗,但是在省去了时间上的消耗,是一个模板函数。也就是说在有这些函数的地方都不需要去调用函数,也就不涉及有2种函数可以调用产生的二义性问题。
因此,complex.h这个头文件要被反复包含,要么把所有函数都放到类里面定义,要么全面写在外面,前面加上inline。另外,写成模板类好像也是可以的。
- 头文件中写类的实现出现函数重复定义的问题
- Keil头文件重复定义的问题
- 头文件中定义的内敛函数报重复定义
- 头文件重复定义的问题&宏定义
- 在头文件中用宏定义来避免重复包含,仍然会出现函数重定义的错误
- 在头文件中用宏定义来避免重复包含,仍然会出现函数重定义的错误
- c++ 中头文件重复定义的问题
- C++头文件重复定义问题的处理(转)
- 转 c++ 中头文件重复定义的问题
- C++ 中头文件重复定义的问题
- C++中inline函数的定义可放在头文件中,inline 函数重复出现不会导致连接错误,
- 头文件中全局函数多次引用出现重定义的问题记录
- C++ 头文件中为何添加了#ifndef #define #endif还会出现变量重复定义的问题
- 关于头文件重复包含以及函数重定义问题
- 关于头文件重复包含以及函数重定义问题
- 关于头文件重复包含以及函数重定义问题
- 头文件中添加了防止重复包含的宏,依旧报重复定义的问题
- 解决重复包含一个头文件时变量重复定义的问题
- iOS storyboard创建Navigation Controller
- class
- mysql数据库修改root密码方法
- 字符串操作总结
- Perl脚本按CTRL+C无法退出的解决办法
- 头文件中写类的实现出现函数重复定义的问题
- 求数组中两个元素的最小距离
- iOS 使用代码和storyboard分别创建UITabBarController
- mysql批量插入更新加参数rewriteBatchedStatements
- AngularJS初识--指令相关知识总结
- 自定义View
- oc文件路径
- ehcache缓存实战
- mysql锁表,MVCC以及基础知识、锁、隔离级别、协议