我遇到了这样的问题:
我有一个头文件:
//first variant:
#ifndef LIBRARIES_H
#define LIBRARIES_H
const char a='4';
#endif // LIBRARIES_H
我将它包含在几个.cpp文件中。 一切都很完美。
但突然间,如果我宣布一个指针:
//second variant:
#ifndef LIBRARIES_H
#define LIBRARIES_H
const char *a="asdfgh";
#endif // LIBRARIES_H
请注意,我只声明其中一个(变种)
我只宣告了一次(我试图更改sadfgh或asdfg的名称)。
当我尝试第二个变种时,我先删除,反之亦然。
如果我声明一个指向字符串的指针,我将得到错误“多次包含变量”。 我用qt编译它。我已经删除并重新编译了几次项目。
当然,我可以在main()函数中定义它,但我想知道,这个问题的原因是什么?为什么我不能在头文件中声明指针,然后将其包含在几个源代码文件中?
答案 0 :(得分:5)
const char a='4';
装置
char const a = '4';
您可以向后阅读“4是a
的初始值char
”。
由于此a
是常量,因此它具有内部链接(即它不会向其他翻译单元公开)。
另一方面,
const char *a="asdfgh";
装置
char const * a = "asdfgh";
你可以向后读作“asdfgh”是一个用于初始化a
的数组,它作为指向常量char
的指针。
在这种情况下,a
本身不是const
,因此默认情况下不会获得内部链接:它具有外部链接。
当您将标题包含在两个或多个翻译单元中时,您会得到两个或多个名为a
的全局和不同对象,这些对象违反了C ++的 One Definition Rule (通常是简称为 ODR )。
一种方法是让a
本身const
,
char const * const a = "asdfgh";
现在尝试向后阅读 以理解它。
答案 1 :(得分:3)
Edit2 显然,我之前提出的改变
的建议const char* a = "asdfgh"
到
const char[6] a= "asdfgh"
的工作原理。
我还在调查它,但是当你声明一个指针时,你只是说该指针是常量,而不是它所指向的内存。当你声明一个数组时,你会说const后面的数据也是不可变的。我正在进一步研究它。
Edit3:this的第二段解释了发生了什么。
此外,“干杯”的答案解释得很清楚。
答案 2 :(得分:-1)
Cheer的答案比我的好,但是......
尝试将声明更改为:
extern const char * const a;
然后在你的一个cpp文件中说:
const char * a = "asdf";
(但如果你有两个竞争对手,
const char * const a = "asdf";
应该有效。)
除非您同时拥有两个consts,否则不会获得静态链接。因此,如果您同时使用两个consts,它应该工作,extern或static。