通过指向self的非const指针在const方法内修改self
题
在下面的例子中 const
对象可以通过 const
方法,因为在该方法中它通过 non-const
指针。(ideone上的相同程序)
#include <iostream>
struct Object;
Object * g_pObject;
struct Object
{
Object():m_a(0){}
void ModifySelfViaConstMethod() const
{
g_pObject->m_a = 37;
}
int m_a;
};
int main()
{
Object o;
g_pObject = &o;
const Object & co = o;
std::cout << co.m_a << "\n";
co.ModifySelfViaConstMethod();
std::cout << co.m_a << "\n";
return 0;
}
我不太擅长阅读c++标准,所以我在这里问:
标准对此有什么看法?
a)const
方法并不能保证你的对象在你做这样的事情时保持未修改
b)它是否定义良好,并且必须编译
c)其他?
解决方案
标准对此有什么看法?
它说(意译) this
有类型 const Object *
, ,这样就不能通过直接修改成员或调用非const成员函数 this
.它没有说明你可以用函数可能访问的任何全局变量做什么;它仅控制对调用函数的对象的直接访问。
const
方法并不能保证你的对象在你做这样的事情时保持未修改
不,它没有。它声明了函数不会修改对象的意图,并提供了一些防止意外破坏该意图的保护。这并不妨碍一个精神错乱的程序员使用 const_cast
, ,或者(如这里)通过全局变量不受控制的耦合来打破承诺。
它是否定义良好,并且必须编译
是的. o
本身不是常量,所以没有什么可以阻止你使用非const指针或对它的引用。该 const
在成员函数上,仅通过以下方式限制对对象的访问 this
, ,而不是通过其他指针到任意对象。
其他提示
当你声明 const
功能,这是"为你好"。
换句话说,你声明它 const
因为根据您的初始设计,它不应该更改在运行时调用它的任何对象。
如果在这个函数的实现过程中,你最终改变了对象,编译器会"对你大喊大叫",告诉你这是错误的。
当然,编译器将能够识别这样的尝试,只有当应用于 this
.
在给定的示例中,编译器无法识别问题,因为它需要比较 this
和 g_pObject
, ,并且这样的比较只能在运行时进行。
当一个方法被声明为 const
, ,编译器确保由 this
指针不被修改。如果您尝试修改 this
实例,编译器失败。但是,编译器无法知道 g_pObject
和 this
实际上是指向同一个实例。这需要一个运行时比较,并且没有编译器会浪费时间对在a中使用的每个指针进行运行时比较。 const
方法在关闭的机会,他们 可能 匹配 this
指针。所以如果你要修改一个 Object
通过一个外部指针,你将不得不做你自己的检查,例如:
void ModifySelfViaConstMethod() const
{
if (g_pObject != this)
g_pObject->m_a = 37;
}
C++中的恒定性是一种安全工具,而不是安全性。
遵守恒常性的代码很可能会按预期工作,并且所有有意将恒常性丢弃的尝试都将由编译器发出警报。
在"我知道我在做什么"的情况下,人们可以找到各种各样的工具,从 const_cast
营办商及 mutable
平庸的C风格演员的关键字。