Nav*_*K N 0 c++ constants const-correctness
请考虑以下代码.
struct foo
{
};
template<typename T>
class test
{
public:
test() {}
const T& value() const
{
return f;
}
private:
T f;
};
int main()
{
const test<foo*> t;
foo* f = t.value();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
t是一个const变量,value()是一个返回的常量成员函数const T&.AFAIK,const类型不能分配给非const类型.但如何foo* f = t.value();编译好.如何发生这种情况以及如何确保value()只能分配给const foo*?
编辑
我发现,这是在使用模板时发生的.以下代码按预期工作.
class test
{
public:
test() {}
const foo* value() const { return f; }
private:
foo* f;
};
int main()
{
const test t;
foo* f = t.value(); // error here
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么在使用模板时会出现问题?
因为你有两个间接级别 - 在你的main函数中,该调用value返回对一个指向非const的const指针的引用foo.
这可以安全地复制到非const指针到非const foo.
如果你实例test有const foo *,这将是一个不同的故事.
const test<const foo*> t;
foo* f = t.value(); // error
const foo* f = t.value(); // fine
return 0;
Run Code Online (Sandbox Code Playgroud)
更新
来自评论:
value()返回const T&只能分配给另一个const类型.但在这种情况下,编译器可以安全地进行转换.
只能读取Const数据.它不能写("变异").但是复制一些数据是一种阅读方式,所以没关系.例如:
const int c = 5;
int n = c;
Run Code Online (Sandbox Code Playgroud)
在这里,我有一些const数据c,我将数据复制到非const变量n中.没关系,它只是读取数据.值in c尚未修改.
现在,假设你foo有一些数据:
struct foo { int n; };
Run Code Online (Sandbox Code Playgroud)
如果我有一个指向其中一个的非const指针,我可以n通过指针修改该值.您要求您的test模板存储指向非const的指针foo,然后创建一个const实例test.因此,只有指针地址是常量.没有人可以改变存储在指针里面的地址test,因此不能指向另一个对象.但是,它指向的对象可以修改其内容.
更新2:
当您创建示例的非模板版本时,您犯了一个错误.要做到正确,你需要替换foo *到每个有的地方T.
const T& value() const
Run Code Online (Sandbox Code Playgroud)
请注意,您在T那里引用了const .所以返回值将是对const的引用:a foo *.它只是指针地址无法修改.它指向的对象可以修改其内容.
在第二个示例中,您删除了引用部分,它更改了含义并使const修饰符应用于指针指向的对象,而不是应用于指针本身.