由于One Definition Rule,C或C ++中不允许对全局变量进行多次定义。但是,在C ++中,const全局变量可以在多个编译单元中定义而没有错误。这与C中的不同。
为什么C ++允许这样做而C不允许?与C相比,为什么const全局的使用和行为在C ++中以这种方式与非const全局不同? C ++和C关于const的内容正在发生什么?
例如,这在C ++中是允许的,但在C:
中是错误的// Foo.cpp
const int Foo = 99;
// Main.cpp
const int Foo = 99;
int main()
{
cout << Foo << endl;
return 0;
}
这对C来说很好,但C ++有问题:
// Foo.cpp
const int Foo = 99;
// Main.cpp
extern const int Foo;
int main()
{
cout << Foo << endl;
return 0;
}
答案 0 :(得分:27)
// Foo.cpp
const int Foo = 99;
// Main.cpp
const int Foo = 99;
命名空间范围内的 const
变量具有内部链接。所以它们基本上是两个不同的变量。没有重新定义。
来自@ David的评论,3.5 / 3 [basic.link]:
具有命名空间范围的名称(3.3.5) 如果是名称,则具有内部链接
的 - 对象,参考,功能或 明确的功能模板 声明静态或,
- 一个对象或 显式声明的引用 const并且都没有明确声明 extern也没有声明过 外部联系;或
- 数据成员 一个匿名工会。
在第二种情况下,你应该这样做(正确的方法):
//Foo.h
extern const int Foo; //use extern here to make it have external linkage!
// Foo.cpp
#include "Foo.h"
const int Foo = 99; //actual definition goes here
// Main.cpp
#include "Foo.h"
int main()
{
cout << Foo << endl;
}
答案 1 :(得分:7)
我认为你要求的理由而不是具体的语言规则。
这样做的理由是它使const
变量更容易使用。它为#define
的一个常见用途提供了类型替换。
您可以以完全相同的方式使用#define MAX_COUNT 211
,而不是const int max_count = 211;
,例如共享头文件,无需担心在哪里放置一个定义。
您不能合法地更改const
对象的值,因此在拥有一个对象和具有相同值的多个对象之间没有明显的区别。
由于您可以在头文件中定义const
对象,因此编译器可以直接在编译阶段使用该值,而不必将此类优化延迟到链接时修复。
答案 2 :(得分:6)
基本上,在C ++中,const,非局部变量是真正的常量表达式,或constexpr。这允许很多东西,比如TMP。
const int five = 5;
int main() {
int x[five];
std::array<int, five> arr;
}
在C中,它们只是一个无法修改的变量。也就是说,
const int five = 5;
int main() {
int x[five]; // Technically, this is a variable length array
}
完全等同于
int five = 5;
int main() {
int x[five];
}
实际上,C ++将某些const
变量提升为新类别constexpr
,而在C中,这不存在,它们只是碰巧不可修改的变量。
答案 3 :(得分:3)
它看起来像 const doesn't actually generate an external symbol。
答案 4 :(得分:0)
为什么英国人拼写COLOR,而美国人拼写COLOR?
它们是来自同一基础的两种不同语言,但它们没有相同的规则。
C&amp; C&amp; C ++是一样的。如果他们没有什么不同,他们都会被称为同一件事。答案 5 :(得分:-2)
我的解决方法是将其声明为:
static classfoo foo;
它适用于我的情况。