C++库引用有关问题
C++库引用问题
问题如下:
我定义了一个公共头文件,暂定为pub.h
//pub.h
#ifndef _PUB_H_
#define _PUB_H_
#include <iostream>
#include <string>
const char* myStr= "test ";
#endif
由于它引用了stl库,在很多需要的地方我都只需要引用它就够了(保证无交叉引用),比如:
在A.h、B.h、C.h、Main.cpp 都只引用pub.h
最后编译时报错,意思是我重复定义了常量myStr,我就不懂了,
难道#ifndef #endif是摆设?
最后我把“const char* myStr= "test "” 独立写一个文件,在需要是才引用就没问题了。
或者,改为“static const char* myStr= "test "”就可以了。
求解,谢谢!
------解决方案--------------------
变量,函数体和类的实现部分不要放在h文件中(除了加static或extern修辞),否则在多个文件引用时会引起链接错误
因此函数体和类的实现部分最好放在cpp文件中
因为多个文件引用时编译器认为给定 symbol 被多次定义
(msdn)
解决方案有:
在 .h 中声明变量:extern BOOL MyBool;,然后在 .c 或 .cpp 文件中向它分配:BOOL MyBool = FALSE;。
将变量声明为 static。
将变量声明为 selectany。
------解决方案--------------------
同意楼上,这个应该是编译器规定吧 或者是标准?
------解决方案--------------------
//pub.h
#ifndef _PUB_H_
#define _PUB_H_
#include <iostream>
#include <string>
const char* myStr= "test ";
#endif
//a.cpp
#include "pub.h "
//b.cpp
#include "pub.h "
a.cpp和b.cpp编译后的a.obj和b.obj中都会有const char* myStr= "test ";,他们链接后都要在程序内存的数据区,很明显冲突了
改为static const char* myStr= "test "”后,c++语法规定,由static修饰的变量有内部连接期(internal linkage),因此当编译成a.obj和b.obj后,由于仅属于该文件,链接后内存中将用文件标识,因此就不存在冲突了
注意:是链接期的问题
------解决方案--------------------
照java理解
static初始化一次
非static,include两次,重复定义
------解决方案--------------------
The One-Definition Rule
Affectionately known as the ODR, the one-definition rule is a cornerstone for the well-formed structuring of C++ programs. The most common consequences of the ODR are simple enough to remember and apply: Define noninline functions exactly once across all files, and define classes and inline functions at most once per translation unit, making sure that all definitions for the same entity are identical.
However, the devil is in the details, and when combined with template instantiation, these details can be daunting. This appendix is meant to provide a comprehensive overview of the ODR for the interested reader. We also indicate when specific related issues are expounded on in the main text.
看一下C++ Templates附录A的The One-Definition Rule, 描述得很清楚。
问题如下:
我定义了一个公共头文件,暂定为pub.h
//pub.h
#ifndef _PUB_H_
#define _PUB_H_
#include <iostream>
#include <string>
const char* myStr= "test ";
#endif
由于它引用了stl库,在很多需要的地方我都只需要引用它就够了(保证无交叉引用),比如:
在A.h、B.h、C.h、Main.cpp 都只引用pub.h
最后编译时报错,意思是我重复定义了常量myStr,我就不懂了,
难道#ifndef #endif是摆设?
最后我把“const char* myStr= "test "” 独立写一个文件,在需要是才引用就没问题了。
或者,改为“static const char* myStr= "test "”就可以了。
求解,谢谢!
------解决方案--------------------
变量,函数体和类的实现部分不要放在h文件中(除了加static或extern修辞),否则在多个文件引用时会引起链接错误
因此函数体和类的实现部分最好放在cpp文件中
因为多个文件引用时编译器认为给定 symbol 被多次定义
(msdn)
解决方案有:
在 .h 中声明变量:extern BOOL MyBool;,然后在 .c 或 .cpp 文件中向它分配:BOOL MyBool = FALSE;。
将变量声明为 static。
将变量声明为 selectany。
------解决方案--------------------
同意楼上,这个应该是编译器规定吧 或者是标准?
------解决方案--------------------
//pub.h
#ifndef _PUB_H_
#define _PUB_H_
#include <iostream>
#include <string>
const char* myStr= "test ";
#endif
//a.cpp
#include "pub.h "
//b.cpp
#include "pub.h "
a.cpp和b.cpp编译后的a.obj和b.obj中都会有const char* myStr= "test ";,他们链接后都要在程序内存的数据区,很明显冲突了
改为static const char* myStr= "test "”后,c++语法规定,由static修饰的变量有内部连接期(internal linkage),因此当编译成a.obj和b.obj后,由于仅属于该文件,链接后内存中将用文件标识,因此就不存在冲突了
注意:是链接期的问题
------解决方案--------------------
照java理解
static初始化一次
非static,include两次,重复定义
------解决方案--------------------
The One-Definition Rule
Affectionately known as the ODR, the one-definition rule is a cornerstone for the well-formed structuring of C++ programs. The most common consequences of the ODR are simple enough to remember and apply: Define noninline functions exactly once across all files, and define classes and inline functions at most once per translation unit, making sure that all definitions for the same entity are identical.
However, the devil is in the details, and when combined with template instantiation, these details can be daunting. This appendix is meant to provide a comprehensive overview of the ODR for the interested reader. We also indicate when specific related issues are expounded on in the main text.
看一下C++ Templates附录A的The One-Definition Rule, 描述得很清楚。