'const'方法可以改变什么?

Dan*_*iel 24 c++

C++方法允许const限定符指示该方法不更改对象.但是,这是什么意思?例如.如果实例变量是指针,它是指意味着指针没有改变,还是它们指向的内存没有改变?

具体来说,这是一个最小的示例类

class myclass {
  int * data;

  myclass() {
    data = new int[10];
  }

  ~myclass() {
    delete [] data;
  }

  void set(const int index) const {
    data[index] = 1;
  }
};
Run Code Online (Sandbox Code Playgroud)

该方法set是否正确符合条件const?它不会更改成员变量data,但确实会更改数组的内容.

Ton*_*roy 22

'const'方法可以改变什么?

如果没有明确地抛弃constness,const方法可以改变:

  • mutable 数据成员,和
  • 该类const无法访问的任何数据,无论该数据是否可访问:
    • 通过指针或引用的成员变量,
    • 通过作为函数参数传递的指针或引用,
    • 通过函数返回的指针或引用,
    • 直接在包含它的命名空间或类(用于静态)中.

对于class/ struct/ union类型的成员,它依赖于其成员函数的常量来确定应该允许哪些操作.(它也可以改变任何非const局部变量和值的参数,但我知道这不是你感兴趣的).

它可以调用const具有相同能力和限制的其他方法.

例如.如果实例变量是指针,它是指意味着指针没有改变,还是它们指向的内存没有改变?

这意味着指针不能(容易/意外地)改变.它并不意味着指向的内存不能更改.

你偶然发现的是一个const函数的逻辑错误,它改变了对象概念上所拥有的指向或引用的数据.正如您所发现的,编译器不会强制执行const您可能想要或期望的正确性.这有点危险,但意味着不需要为其他对象的指针/引用显式删除constness,这些对象可能会被更改为const函数的副作用.例如,日志记录对象.(通常,这些对象在逻辑上并不由其const功能在其上运行的对象"拥有" .)关键是编译器无法可靠地区分对象具有指向数据的逻辑所有权的类型,因此它是不得不猜测某种方式,并允许程序员覆盖,或不受const-ness 保护.C++放弃了保护.

有趣的是,我听说Walter Bright的D语言翻转了这个默认值,const默认情况下在const函数中生成指向数据.这对我来说似乎更安全,但很难想象一个人最终需要多久才能明确地抛弃常量以允许想要的副作用,以及这是否会令人满意的精确或烦人的冗长.


Ker*_* SB 17

最简洁的是,它意味着类型thisconst T *const成员函数,哪里T是你的类,而在非限定函数中则是T *.

您的方法set不会更改data,因此可以限定为const.换句话说,myclass::data是作为this->data类型访问的int * const.

  • *我*不会使用C阵列!:-) (4认同)
  • André:`std :: vector`实际上并没有在内部使用array-of-T,因为它想要将内存分配与构造分开...... (2认同)

And*_*ron 6

这个问题有两个方面:

  1. 什么const对编译器意味着什么?
  2. const当编译器无法验证时如何应用?

问题1

第一个很简单.编译器验证没有数据成员被修改(除非它们被限定为mutable).它以递归方式验证:对于任何用户定义的类型,它会检查是否没有调用非const方法.对于内置类型,它验证它们未分配.

对指针的转换是T*T*const(常量指针),而不是const T*(指针为const).这意味着编译器不会验证指向的对象是否未被修改.显然,这导致问题2.

问题2

const未经编译器验证时如何应用?它意味着它对您的应用程序应该意味着什么.这通常称为逻辑const.当使用const相对于逻辑常量性是受到辩论.


归档时间:

查看次数:

7311 次

最近记录:

14 年,7 月 前