Q1:
我最近读过书C++ Primer
,当我读到以下内容时:
要替换变量的值,编译器必须查看变量的初始值设定项。当我们将程序拆分为多个文件时,使用const的每个文件都必须能够访问其初始化程序。为了查看初始化程序,必须在每个想要使用变量值的文件中定义变量。
我有一个问题:当我使用其他文件中定义的变量时,我只是使用extern
来声明就足够了,我为什么要must have access to its initializer
,所以我做了一个测试:
在main.cpp中,我在下面写道:
#include <iostream>
using namespace std;
extern int test;
int main()
{
cout << test << endl;
return 0;
}
在test.cpp中,我在下面写道:
int test = 100;
顺便说一下,这两个文件是在同一个项目中添加的,否则就无法成功构建。 当我运行它们时,它会打印
像我期待的那样。但是在main.cpp中,我不需要像书中所说的那样定义像100
int test = 100
这样的东西。我不知道谁是对的。
Q2:
int i = 43;
const int &r = i;
i = 1; //when i changed, r alse changed
我已经在gcc 4.7和visual studio 2013中测试过,它们都得到了相同的结果,
改变了。那么,const
有什么意义呢?不应该总是43岁吗?
答案 0 :(得分:3)
我认为这本书的引用意味着类似下面的内容
const size_t N = 10;
int main()
{
int a[N];
//...
}
如果在具有说明符extern
的某个其他模块中定义常量N,则在具有main的模块中,编译器无法访问常量的值,因此无法定义数组< / p>
extern const size_t N;
int main()
{
int a[N]; // error: the value N is unknown
//...
}
由于这个原因,常量具有内部链接,因此可以在每个模块中定义它们,在编译时需要它们的值。
对于第二个问题,然后使用常量引用来防止使用引用修改引用的对象。
例如,如果您希望某些函数不会更改复合对象,则可以将其参数声明为对象的常量引用。
临时对象也绑定到常量引用。
考虑一个例子
void display_string( const std::string &s )
{
std::cout << s << std::endl;
}
您可以使用字符数组调用该函数。例如
display_string( "Hello, World" );
编译器隐式将字符串文字转换为类型为std::string
的临时对象,并将其绑定到参数的常量引用。
如果参数不会被声明为常量引用,例如
void display_string( std::string &s );
然后编译器会发出错误。
使用常量引用时,假设客户端代码不会更改引用的对象本身。
这是客户端代码可能会查看对象,但可能无法用手触摸它。:)
答案 1 :(得分:0)
Q1。 have access to its initializer
表示编译器需要知道变量的初始值设定项(定义)。你可以让编译器通过链接main.cpp和test.cpp来实现它。你说these two files are added in the same projects
,所以IDE会为你做这件事。
您可以在this question上找到更多信息。
Q2。编译器不允许您更改r
的值,因为它是对const变量的引用,但i
是一个整数变量,因此您可以更改它的值。