Can a heap-allocated object be const in C++?

a 夏天 提交于 2019-11-27 01:20:37

问题


In C++ a stack-allocated object can be declared const:

const Class object;

after that trying to call a non-const method on such object is undefined behaviour:

const_cast<Class*>( &object )->NonConstMethod(); //UB

Can a heap-allocated object be const with the same consequences? I mean is it possible that the following:

const Class* object = new Class();
const_cast<Class*>( object )->NonConstMethod(); // can this be UB?

is also undefined behaviour?


回答1:


Yes. It's legal to construct and destroy a const heap object. As with other const objects, the results of manipulating it as a non-const object (e.g. through a const_cast of a pointer or reference) causes undefined behaviour.

struct C
{
        C();
        ~C();
};

int main()
{
        const C* const p = new const C;

        C* const q = const_cast<C*>(p); // OK, but writes through q cause UB

        // ...

        delete p; // valid, it doesn't matter that p and *p are const

        return 0;
}



回答2:


In your heap example, new returns a pointer to non-const. The fact that you've stored it in a pointer to const (and then const_casted it back to a pointer to non-const) doesn't change the fact that the object itself is not const in the same way as the stack-allocated one is.

However, you can create a const object on the heap:

const Class* object = new const Class();

In such a case, casting to a pointer to non-const and calling a non-const method would be the same situation as the const stack-allocated object.

(The idea of creating a const object on the heap was new to me, I had never seen that before. Thanks to Charles Bailey.)




回答3:


Yes, a heap-allocated object can be const. Consider this excerpt from the example in 7.1.5.1/5:

const int* ciq = new const int (3);    // initialized as required
int* iq = const_cast<int*>(ciq);       // cast required
*iq = 4;                               // undefined: modifies a const object

The example you gave in the question is fine because you're not asking new to make a const object; you're just storing the result in a pointer-to-const.




回答4:


Don't forget mutable members

It won't be undefinied behaviour if the NonConstMethod only modifies mutable qualified members (see 7.1.5.1 (4)) of a const qualified class. Yes, otherwise it's undefined behaviour.

const A* p = new(const A);
A *q = const_cast<A*>(p);
q->NonConstMethodThatModifiesMembers();             // undefined behaviour!
q->NonConstMethodThatOnlyModifiesMutableMembers();  // defined behaviour!



回答5:


Obviously:

struct Foo {
  const int Bar;
  Foo() : Bar(42) { }
};

Foo* foo = new Foo;
const_cast<int&>(foo->Bar); // don't do this.



回答6:


const_cast can cause UB when the object is actually read-only (for example, the compiler can create such objects when you use hard coded strings in your code, by placing them in certain memory areas that are read only) for some reason. This will not happen with heap allocated objects, no matter how you keep their reference (const pointer, const reference, whatever).



来源:https://stackoverflow.com/questions/1927477/can-a-heap-allocated-object-be-const-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!