sha*_*oth 9 c++ constructor destructor const undefined-behavior
C++标准说修改最初声明的对象const是未定义的行为.但那么构造函数和析构函数如何运作?
class Class {
public:
Class() { Change(); }
~Class() { Change(); }
void Change() { data = 0; }
private:
int data;
};
//later:
const Class object;
//object.Change(); - won't compile
const_cast<Class&>( object ).Change();// compiles, but it's undefined behavior
Run Code Online (Sandbox Code Playgroud)
我的意思是构造函数和析构函数与调用代码完全相同,但是允许它们更改对象并且不允许调用者 - 他会遇到未定义的行为.
它应该如何在实施和标准下工作?
Mic*_*urr 15
该标准明确允许构造函数和析构函数处理const对象.从12.1/4"构造者":
构造函数可以被调用用于
const,volatile或const volatile对象....const和volatile语义(7.1.5.1)不适用于正在构建的对象.只有当派生的对象(1.8)的构造函数结束时,这种语义才会生效.
和12.4/2"析构函数":
析构函数可以调用一个
const,volatile或const volatile对象....const和volatile语义(7.1.5.1)不适用于被破坏的对象.一旦最派生对象(1.8)的析构函数启动,这种语义就会停止生效.
作为背景,Stroustrup在"C++的设计和演变"(13.3.2对定义的细化const)中说:
为了确保某些(但不是全部)
const对象可以放置在只读存储器(ROM)中,我采用了一个规则,即任何具有构造函数的对象(即,所需的运行时初始化)都不能放在ROM中,而是其他const对象可以....
声明的对象
const在构造函数完成之前被认为是不可变的,直到它的析构函数开始.在这些点之间写入对象的结果被认为是未定义的.在最初的设计中
const,我记得认为理想const是一个在构造函数运行之前可写的对象,然后由一些硬件魔法变为只读,最后进入析构函数后再次变为可写.可以想象一个实际上以这种方式工作的标记架构.如果有人可以写入定义的对象,这样的实现会导致运行时错误const.另一方面,有人可以写入未定义的const已作为const引用或指针传递的对象.在这两种情况下,用户都必须先抛弃const.这种观点的含义是,抛弃const最初定义的对象const然后写入它最多是未定义的,而对最初未定义的对象执行相同操作const是合法且定义良好的.请注意,通过对规则的这种改进,其含义
const并不取决于类型是否具有构造函数; 原则上,他们都这样做.const现在声明的任何对象可以放在ROM中,放在代码段中,受访问控制等保护,以确保它在收到初始值后不会发生变异.但是,这种保护并不是必需的,因为目前的系统通常不能保护每const一种形式的腐败.
| 归档时间: |
|
| 查看次数: |
1379 次 |
| 最近记录: |