问题描述
|
由于一个定义规则,在C或C ++中不允许对全局变量进行多重定义。但是,在C ++中,可以在多个编译单元中毫无错误地定义const全局变量。这与C语言不同。
为什么C ++允许这样做而C不允许呢?与C相比,为什么在C ++中const全局的用法和行为与非const全局在这种方式上不同?关于const,C ++和C在幕后发生了什么?
例如,这在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;
}
解决方法
// Foo.cpp
const int Foo = 99;
// Main.cpp
const int Foo = 99;
命名空间范围内的“ 3”变量具有内部链接。因此,它们基本上是两个不同的变量。没有重新定义。
来自@David \的评论,3.5 / 3 [basic.link]:
具有名称空间范围的名称(3.3.5)
有内部链接(如果是名称)
的
—对象,引用,功能或
显式的功能模板
声明为静态或,
—对象或
明确声明的引用
const且未明确声明
外部或以前没有声明
外部联系;要么
—数据成员
匿名工会的身份。
在第二种情况下,您应该这样做(正确的方法):
//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;
}
, 我认为您是在要求基本原理,而不是允许这样做的特定语言规则。
这样做的理由是它使3个变量更易于使用。它为#define
的一种常用用法提供了有类型的替换。
您可以完全相同的方式使用const int max_count = 211;
来代替#define MAX_COUNT 211
,例如共享的头文件,而不必担心将一个定义放在何处。
您无法合法地更改const
对象的值,因此在拥有一个对象和具有相同值的多个对象之间没有明显的区别。
正如您可以在头文件中放置“ 3”对象的定义一样,它使编译器在编译阶段直接使用该值变得很简单,而不必将此类优化延迟到链接时修正。
, 基本上,在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
变量提升为一个新类别category15ѭ,而在C中,这并不存在,它们只是碰巧不可修改的变量。
, 看起来const实际上并没有生成外部符号。
, 为什么英国人会拼写颜色,而美国人会拼写颜色?
它们是来自同一基础的2种不同语言,但是它们没有相同的规则。
C和C ++相同。如果它们没有不同,它们将被称为同一件事。
, 我的解决方法是将其声明为:
static classfoo foo;
它适合我的情况。