从 const 方法调用成员上的非常量方法

Invoking a nonconst method on a member from a const method

本文关键字:方法 非常 常量 成员 const 调用      更新时间:2023-10-16

我很惊讶地在"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* aPtrconst A* aPtr,这使得调用非常量A::nonconst()是非法的。

对象的"常量">不会通过指针扩展到其他对象。在您的示例中,const部分是整个对象a,或者是指针aPtr。因为aPtr是一个A *而不是一个const A *,所以你可以调用一个非常量的方法。

如果您更改

A* aPtr ;

const A* aPtr ;

那么你将无法打电话给aPtr->nonconst().

const的语言定义

我很惊讶地在"常量"中发现了这个"洞":

没有。

const统一适用于所有类成员:在类 Cconst 成员函数中,this 具有类型 const C *,因此对于一个成员C::mem声明为 T 类型:

class C {
// ...
    T mem;
};

this->mem具有类型 const T

请选取类型来辨别声明的T类型以及所有成员的相应符合 const 资格的类型。

似乎是一个问题(它有点在我的代码中,我在哪里找到它。

仅仅因为规则的系统应用没有达到你的期望并不意味着规则有问题,而是意味着你的期望有问题。

您应该写下您的期望,以查看如果const不同的类型,您期望非统一应用程序。

当你编程时,你必须逻辑推理。你应该推断事物,而不是在没有逻辑理由的情况下期待它们。

正确使用const

为什么?

你的类被称为AB,很难理解什么构成逻辑状态,什么不构成逻辑状态。 ;)你问一个"道德"问题(不仅仅是关于合法/非法C++程序的问题(,你的代码片段没有"道德"价值。如果你真的发布了相关的代码,我们可能会对它做出一些"道德"判断。

逻辑状态

您应该声明const不会更改其所应用到的对象的"逻辑状态"的函数。

这意味着你必须定义类实例的"逻辑状态"是什么:它是一个抽象的概念,只有你可以定义它,因为它是一个高级概念。"逻辑状态"与类应该解决的问题有关。

然后你可以辨别哪些变量对逻辑状态有贡献:*(b.aPtr)b的逻辑状态有贡献吗?

密切相关的问题

你知道复制构造函数吗?

关于复制赋值运算符?

关于析构函数?