Re: const-correctness loopholes
Il 15/04/2011 22.15, Kai-Uwe Bux ha scritto:
noir wrote:
int main ( void ) {
{
int i = 5;
example x (&i );
*x.p = 6;
std::cout<< i<< "\n";
}
{
int i = 5;
example const x (&i );
// *x.p = 6; // fails to compile! deep const
}
{
int i = 5;
example const x (&i );
int_ptr p ( x.p ); // initializing from x, which is const!
*p = 6;
std::cout<< i<< "\n";
}
}
This very interesting, but I would not call it a loophole. Rather, a
careless implementation of the const_correct_ptr class.
If I understand correctly, in this line:
int_ptr p ( x.p ); // initializing from x, which is const!
the compiler is calling the default constructor for const_correct_ptr,
that would look something like this:
const_correct_ptr(const_correct_ptr const& rhs)
{
the_ptr = rhs.the_ptr;
}
Of course, this bypasses any const-correct interface or whatever, and
copies the raw pointer to the new non-const object, so game over.
However, with a little more effort, I believe the programmer of the
const_correct_ptr class can enforce the right behaviour, very unlike the
const_cast that effectively throws a monkey wrench on the whole
const-correctness issue (and looks to me as a real loophole).
I can see two ways to close the "loophole" you presented:
Solution 1
----------
If the original class is supposed to share the pointer, than we can
define a const correct accessor:
const_pointer getThePointer() const { return the_ptr; }
pointer getThePointer() { return the_ptr; }
and replace the default copy constructor with this one:
const_correct_ptr(const_correct_ptr const& rhs)
{
the_ptr = rhs.getThePointer(); // use const-correct accessor
}
This does not (correctly) compile anymore (failure to convert from
"const int *" to "int *" in the line above)
Solution 2
----------
If the original class is NOT supposed to share the pointer, then we can
simply replace the default shallow-copy constructor with a deep-copy
constructor:
const_correct_ptr(const_correct_ptr const& rhs)
{
the_ptr = new T(*the_ptr);
}
Thanks for your insights,
noir