从 const 方法调用成员上的非常量方法
Invoking a nonconst method on a member from a const method
我很惊讶地在"const"ness中发现了这个"洞":
#include <stdio.h>
class A
{
int r ;
public:
A():r(0){}
void nonconst()
{
puts( "I am in ur nonconst method" ) ;
r++;
}
} ;
class B
{
A a ;
A* aPtr ;
public:
B(){ aPtr = new A() ; }
void go() const
{
//a.nonconst() ; // illegal
aPtr->nonconst() ; //legal
}
} ;
int main()
{
B b ;
b.go() ;
}
所以基本上从const
方法B::go()
,如果指针引用了 A
类型的对象,你可以调用非常量成员函数(恰如其分地命名为 nonconst()
(。
为什么? 似乎是一个问题(它有点在我的代码中,我在哪里找到它。
当 B
类型的对象是 const 时,则它的所有成员都是 const,这意味着它的两个成员在 B::go()
的持续时间内是有效的
A const a;
A * const aPtr;
第一个是 A
类型的常量对象,您只能在其上调用 const 成员函数。 但是,第二个是指向非常量A
的常量指针。 你不能合法地说aPtr = <anything>
函数B::go()
,因为这会修改aPtr
,这是常数。
一个指向常量A
的指针将被声明为A const* aPtr
或const A* aPtr
,这使得调用非常量A::nonconst()
是非法的。
对象的"常量">不会通过指针扩展到其他对象。在您的示例中,const
部分是整个对象a
,或者是指针aPtr
。因为aPtr
是一个A *
而不是一个const A *
,所以你可以调用一个非常量的方法。
如果您更改
A* aPtr ;
自
const A* aPtr ;
那么你将无法打电话给aPtr->nonconst()
.
const
的语言定义
我很惊讶地在"常量"中发现了这个"洞":
没有。
const
统一适用于所有类成员:在类 C
的 const
成员函数中,this
具有类型 const C *
,因此对于一个成员C::mem
声明为 T
类型:
class C {
// ...
T mem;
};
this->mem
具有类型 const T
。
请选取类型来辨别声明的T
类型以及所有成员的相应符合 const 资格的类型。
似乎是一个问题(它有点在我的代码中,我在哪里找到它。
仅仅因为规则的系统应用没有达到你的期望并不意味着规则有问题,而是意味着你的期望有问题。
您应该写下您的期望,以查看如果const
不同的类型,您期望非统一应用程序。
当你编程时,你必须逻辑推理。你应该推断事物,而不是在没有逻辑理由的情况下期待它们。
正确使用const
为什么?
你的类被称为A
和B
,很难理解什么构成逻辑状态,什么不构成逻辑状态。 ;)你问一个"道德"问题(不仅仅是关于合法/非法C++程序的问题(,你的代码片段没有"道德"价值。如果你真的发布了相关的代码,我们可能会对它做出一些"道德"判断。
逻辑状态
您应该声明const
不会更改其所应用到的对象的"逻辑状态"的函数。
这意味着你必须定义类实例的"逻辑状态"是什么:它是一个抽象的概念,只有你可以定义它,因为它是一个高级概念。"逻辑状态"与类应该解决的问题有关。
然后你可以辨别哪些变量对逻辑状态有贡献:*(b.aPtr)
对b
的逻辑状态有贡献吗?
密切相关的问题
你知道复制构造函数吗?
关于复制赋值运算符?
关于析构函数?
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 我刚刚创建了一个非常快速的素数排序方法.如何改进?
- 是否有一种有效的,适当的方法将非常大的公共班级枚举放在利用它们的公共方法之下,以使代码更加干净
- 在非常相似的方法之间共享代码
- C/C++中最有效的方法是为非常大的数据集修剪除1个空白之外的额外空白
- 必须有一种非常快速的方法来计算此按位表达式
- 从仿真数据构建非常大的马尔可夫链的最佳/最快方法是什么?
- 在 c++ 中搜索文件中的字符串以查找非常大的输入的有效方法
- 从getter方法返回常量和非常量值
- 覆盖保存文件的非常安全的方法
- 在一个非常复杂的程序中,替换系统的最佳方法是什么
- QTcpSocket每~0.5s才读取一次数据,即使是非常小的数据包,任何方法都可以加快速度
- 非常具体的子类方法调用
- CMakelists.txt要在windows和mac上工作是非常复杂的,有更好的方法吗?
- c++(非c++ 11)在非常大的方法中释放数组的最佳方式
- 使用QtConcurrentRun和互斥的非常简单的方法有时会出现分段错误
- C++运算符<<和头文件中的>>方法,做得非常错误