问题如下:
我定义了一个公共头文件,暂定为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"”就可以了。
求解,谢谢!

解决方案 »

  1.   

    变量,函数体和类的实现部分不要放在h文件中(除了加static或extern修辞),否则在多个文件引用时会引起链接错误
    因此函数体和类的实现部分最好放在cpp文件中因为多个文件引用时编译器认为给定 symbol 被多次定义
    (msdn)
    解决方案有: 
    在 .h 中声明变量:extern BOOL MyBool;,然后在 .c 或 .cpp 文件中向它分配:BOOL MyBool = FALSE;。 
    将变量声明为 static。 
    将变量声明为 selectany。
      

  2.   

    //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后,由于仅属于该文件,链接后内存中将用文件标识,因此就不存在冲突了注意:是链接期的问题
      

  3.   

    照java来理解,
    static只初始化一次
    非static,include多次,重复定义
      

  4.   

    照java理解
    static初始化一次
    非static,include两次,重复定义
      

  5.   

    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, 描述得很清楚。
      

  6.   

    一般情况下,变量的定义不可以方在头文件中。因为头文件会被多个translation unit包含。因此当这样的定义出现在多个translation unit中的时候,链接器会认为变量重复定义。但是我发现,如果你定义的是常量的话,那么就可以放在多个translation unit中了。因此头文件中可以包括常量的定义。你试试看(我没有试过)
    const char * const MY_STRING = "test";
      

  7.   

    谢谢各位我有两点不明白
    1、这是常量定义
    2、#ifndef #endif 难道无法保证?
      

  8.   

    1、const char* myStr="test"; myStr并不是常量。myStr是指向常量的指针。但该指针本身是变量。你可以让它再指向别的常量。
    // main.cpp
    ...
    myStr = "quiz";2、#ifndef #endif是防止头文件重复包含。但是当你的头文件中有变量的定义的时候,如果你在两个以上的cpp中都包含了该头文件,那么就会产生重定义。
    // main.cpp
    #include "pub.h"
    // other.cpp
    #include "pub.h"
    每一个源程序文件的编译过程是独立的。因此,在这两个cpp文件中都有一个叫做myStr的变量被定义。因此链接器会认为这是重复定义。
    解决办法有两个。
    第一个办法,改成常量定义。
    第二个办法,在pub.h中写extern const char *myStr;
    在pub.cpp中写const char *myStr = "test";