C++ 多个文件中的常量定义

C++ 多个文件中的常量定义,c++,constants,C++,Constants,我正在读“C++初级读物升级版”。第9章讨论了C++与C在处理常量修饰符:时的区别。 “在C++中(但不是C),const修饰符稍微改变默认存储类,而全局变量默认有外部链接,const全局变量默认具有内部链接。 如果全局常量声明与常规变量一样具有外部链接,这将是一个错误,因为您只能在一个文件中定义全局变量。也就是说,只有一个文件可以包含进程声明,而其他文件必须使用extern关键字提供引用声明。” 我试图用以下程序来测试这一说法: 文件.h: using namespace std; con

我正在读“C++初级读物升级版”。第9章讨论了C++与C在处理常量修饰符:

时的区别。

“在C++中(但不是C),const修饰符稍微改变默认存储类,而全局变量默认有外部链接,const全局变量默认具有内部链接。

如果全局常量声明与常规变量一样具有外部链接,这将是一个错误,因为您只能在一个文件中定义全局变量。也就是说,只有一个文件可以包含进程声明,而其他文件必须使用extern关键字提供引用声明。”

我试图用以下程序来测试这一说法:

文件.h:

using namespace std;

const char *constant = "Magic";
file1.cpp

#include <iostream>
#include "file.h"
extern void file2();
int main(){
  cout << "constant = " << constant << endl;
  file2();
}
In file included from file2.cpp:2:0:
file.h:3:24: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
 char* const constant = "Magic";
                        ^
In file included from file1.cpp:2:0:
file.h:3:24: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
 char* const constant = "Magic";
当我执行此操作时,会收到以下错误消息:

g++ -Wall -g -o file file2.cpp file1.cpp
/tmp/ccdl16Tw.o:(.data+0x0): multiple definition of `constant'
/tmp/ccA3ZEHa.o:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [all] Error 1
gcc版本4.8.2

更新:

如果我这样做

 char* const constant = "Magic";
然后make会给我这个警告:

g++-Wall-g-o文件file2.cpp文件1.cpp

In file included from file2.cpp:2:0:
file.h:3:24: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
 char* const constant = "Magic";
                        ^
In file included from file1.cpp:2:0:
file.h:3:24: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
 char* const constant = "Magic";

const char*常量
不是
const
。它是指向
常量字符
的非
常量指针。作为命名空间范围中的非
const
变量,默认情况下它具有外部链接,因此您会得到多个定义错误

const char*const const constant
const
,它的行为将符合您的预期

更新:

另一方面,
char*const常量
将是指向
char
const
指针。作为
const
,默认情况下,它在名称空间范围中具有内部链接


但是,您不应该使用字符串文字对其进行初始化(正如编译器警告指出的那样),因为这是标准不允许的(这种转换在c++11中是非法的,在此之前已被弃用)。允许将字符串文本存储在只读内存中,并且不允许在运行时修改它们。这就是为什么将指针指向非常量字符的字符串文本是危险的。

您是否尝试过
extern const char*constant,例如
const char*constant=“Magic”在其中一个翻译单元中?全局变量在
/
结构
声明子之外使用时仍然不同。@πάνταῥεῖ 我认为他的意思是
const
应该有内部链接,因此链接器不应该抱怨重复的符号。@vsoftco“我认为他的意思是
const
应该有内部链接”,这显然是错误的,除非按照<代码>结构> <代码>或>代码>类< /代码>也>代码>静态< /代码>,它在C++中的含义不同于C.@ῥεῖ, 我同意vsoftco的观点。这是我从书中的课文中理解的。顺便说一句,我忘了在main()中调用file2,更新了。@πάνταῥεῖ 不,我不认为这是错的
const
默认情况下似乎有内部链接(不需要
static
),我面前没有标准,但我用
const常量=10尝试了OP的程序并且链接器不再抱怨重复。这里的问题是指针不是
const
,正如@user207933 answer所指出的那样。另外,值得注意的是
const
限定其左边的任何内容,除非用作第一个限定符,因此原始定义与
char const*constant
相同
char
const
,但不是指针。在const char*const constant中,第一个const表示指针指向的字符是常量,第二个const表示指针指向的是常量地址,对吗?如果我有char*const constant=“Magic”,这意味着什么?我已经更新了从程序中获得的行为。我会接受你的答案,但如果你能回答这一个额外的问题,那真的很有帮助
char*const constant=“Magic”
表示指针为
const
(即,您不能将指针重新分配到另一个C样式字符串/字符串文字)并指向
char
。C++还禁止使用指向char的指针指向字符串文字,它必须是指向“代码> const char < /C>”的指针。换句话说,
char*const constant=“Magic”
产生了
警告:从字符串常量到“char*”的不推荐的转换
@vsoftco,这解释了很多!请注意:当我使用char*const constant=“Magic”时,编译器会给出警告而不是错误。但我同意这不是一个好的编程practice@dannycrane是的,事实上,在我意识到这一点后,编辑了我的评论。
In file included from file2.cpp:2:0:
file.h:3:24: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
 char* const constant = "Magic";
                        ^
In file included from file1.cpp:2:0:
file.h:3:24: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
 char* const constant = "Magic";