【发布时间】:2011-05-02 21:01:01
【问题描述】:
当 C++ 中的 const 关键字写在成员函数的末尾(参数列表之后)时,它到底是什么意思?
【问题讨论】:
当 C++ 中的 const 关键字写在成员函数的末尾(参数列表之后)时,它到底是什么意思?
【问题讨论】:
这意味着*this 在该成员函数内部是const,即它不会改变对象。
关键字
this是一个prvalue 表达式,其值是调用函数的对象的地址。类X的成员函数中this的类型是X*。如果成员函数声明为const,则this的类型为const X*。 [第 9.3.2 节 §1]在
const成员函数中,调用该函数的对象是通过const访问路径访问的;因此,const成员函数不应修改对象及其非静态数据成员。 [第 9.3.2 节 §2]
这意味着可以在类的const 实例上调用const 成员函数。不能在 [1]const 对象上调用非const 成员函数,因为它可能会尝试修改它。
[1] 注意:临时对象不是const 对象,除非它是const 类型。
【讨论】:
const int* ptr = &m_value
const 正确性有关。任何合理的编译器都将能够自己弄清楚在应用优化时什么是不变的。另外,声明一个成员函数const 并不能立即帮助编译器,因为const 可以被const_cast 编辑掉。 (虽然一般来说你不应该那样做)。
*this 是该成员函数内的const。它是 const 的对象(this 指向的对象)。
const 表示函数承诺不会改变对象。它可以规避甚至违反承诺。详细说明按位与逻辑常量可能很有用。提示mutable 可能也是一个好主意。
const 在函数签名的末尾意味着该函数应该假定它所属的对象是const。实际上,这意味着您要求编译器检查该成员函数不会以任何方式更改对象数据。这意味着要求编译器检查它是否没有直接更改任何成员数据,并且它不会调用任何本身不保证不会更改对象的函数。
当您创建const 对象时,您要求编译器确保该对象在其初始化之后不会更改。这反过来意味着编译器将检查您是否没有直接更改其成员数据,并且您不会调用任何不能保证它不会更改对象的函数。
这都是 const 正确性 哲学的一部分。从本质上讲,这意味着如果事情现在正常运行并且它们不会改变,那么它们将永远不会破裂。换句话说,恒定的事物更容易可靠地处理。函数签名末尾的这个const 是一个工具,可以让你禁止事情被破坏。这反过来意味着您应该将const 放在任何可能的地方。
【讨论】:
const。也就是说,除非您现在知道,在设计类时,应该允许成员函数更改对象。这是一个你应该尽早问自己的设计问题,而且应该很容易回答。这不是“让门稍后打开”。相反,它是关于函数是应该改变对象还是不应该改变它。这是一个是/否的问题,黑色或白色,中间没有任何内容,应该很容易回答。注意:不是可以改变对象,而是应该。
const 对象时,他们只能在该对象上调用const 成员函数。记住这一点。所以我们在这里讨论的是设计一个界面:用户可以调用什么,不可以调用什么。这是一个早期的决定。如果您通过未将函数定义为 const 来“打开门”,那么您将禁止在 const 对象环境中调用该函数。用户喜欢const 对象,因为对象不会改变,因此不会破坏事物。允许这样做的设计。
编译器优化是可能的,但主要好处是强制执行函数声明中表达的契约 - 如果您将成员函数定义为 const,编译器会阻止对该函数内的对象进行任何修改。
您可以在声明中使用mutable 使类中的各个字段不受此限制。例如,当您有一个封装了自己的 lock_guard 的类时,这很有用,即使在 const 成员函数中也必须更改其值以强制线程安全。
【讨论】: