C++
Much literature says const
references cannot be used to modify their referents and const
pointers cannot be used to modify their pointees.
Then, why can they be delete
d?
const int& cirDynamic = *( new int(5) );
// ^ 'const int& cirDynamic = *( &( *( new int(5) ) ) );' gives same output below
cout << cirDynamic << endl; // 5
delete &cirDynamic;
cout << cirDynamic << endl; // garbage value
I know the trailing const in T* const
only prevents the pointer from being reseated, but below I use two const
s, as in const T* const
, for emphasis. Why can the following pointer be delete
d?
const int* const cipcDynamic = new int(5);
// ^ 'const int* const cipcDynamic = &( *( new int(5) ) );' gives same output below
cout << *cipcDynamic << endl; // 5
delete cipcDynamic;
cout << *cipcDynamic << endl; // garbage value
The output shows that at least some dynamically allocated memory was freed. Has all of it been freed, or could there have been copying involved where only the copy was freed?
The non-const version of the const reference snippet (int&
) and the non-leading-const versions of the const pointer const snippet (int* const
and int*
) produce the same output as their more const counterparts. In all 5 cases, why and how is the lifetime of the temporary new-expression extended?
Assuming the corresponding operator has not been overloaded, explicitly deleted, or made non-public if the data type is a class or struct, does the Standard make the following guarantees:
The dereference operator provides direct access to the pointee
The
new
operator produces a pointer to the dynamically allocated memory, not a dynamically allocated copy of the original dynamically allocated memory
If instead the new
operator was overloaded but still returned ::operator new(size)
and the dereference operator was overloaded but still returned a reference to the object, are there any side-effects that would make these two points not hold?
Constness affects objects themselves.
new
anddelete
and constructors affect the creation of objects. It doesn't make sense to ask whether constructors or destructors areconst
, because they run before or after the object exists. Similarly, you can create and destroy constant objects dynamically, and/or you can manage dynamically created objects through constant pointers or references.As a very simple thought experiment, consider this code:
This wouldn't work if constness could prevent the object
x
from being destroyed.'const' in all your examples only prevents you to modify the variable through assignment. That's all it does. It does not prevent delete to reclaim the memory.
In your first example, "const int& cirDynamic" prevents you to write something like "cirDynamic=2". But it's legal to take address of cirDynamic (which will get you a "const int*" pointer), and delete would operate on const pointers happily.
In your second example, "const int* const cipcDynamic", the first const prevents you from modifying the place pointed by the pointer, like "*cipcDynamic = 2", the second const prevents you from modifying the pointer itself to point to another place, like "cipcDynamic = new int".