On Thu, 31 Mar 2005 15:45:48 GMT, Andre Kostur <>
fed this fish to the penguins:
>Gonçalo Rodrigues <> wrote in
>news: :
>
>> Hi all,
>>
>> I have a class, call it Object of heap-allocated objects. They are
>> managed via a smart pointer class Ref (actually a template class but
>> that does not matter for the problem). Object instances are created
>> via a factory method that returns a Ref and all constructors are
>> protected.
>>
>> My "problem" is the following. The Ref class is basically a pointer,
>> e.g. something like
>>
>> class Ref {
>> public:
>> //... some methods.
>>
>> private:
>> Object* ptr;
>> }
>>
>> and it supports all the usual operations for smart pointers like *,
>> ->, assignment -- is particular ptr is *not* const.
>>
>> The constructor is, basically
>>
>> (A)
>>
>> Ref(Object* ptr) : ptr(ptr) {
>> //Do some stuff if this->ptr != 0.
>> }
>>
>> Now, looking at the signature of the constructor, my first temptation
>> was to write
>>
>> (B)
>>
>> Ref(const Object* ptr) : ptr(ptr) {
>> //Do some stuff if this->ptr != 0.
>> }
>>
>> Because in the "do some stuff" part I do *not* change in any way the
>> pointed to Object. But, of course, the compiler complains because I'm
>> assigning a const to a non const. So I was tempted to do
>
>In a certain way of looking at it, you do. OK, you don't modify Object
>within this function, but you do allow for some other function to modify
>Object via the member variable ptr. The only way to make the argument a
>const pointer would be to also make the member variable a const pointer.
>If you can get a non-const pointer out of your Ref class (via operator*,
>or operator-> for example), then you can't make your constructor
>parameter non-const either. If you did, you'd be lying to the user of
>the Ref class (semantically speaking). By making the parameter const,
>you're promising to the user that the Ref class will not modify the
>pointed-to Object, nor will it allow other users of the Ref class to
>modify it either.
>
Thanks, I was not aware of this.
>> (C)
>>
>> Ref(const Object* ptr) : ptr(const_cast<Object*>(ptr)) {
>> //Do some stuff if this->ptr != 0.
>> }
>>
>> but that const_cast sure does leave me nervous.
>>
>> The reason I want to make the signature of the Ref constructor as in
>> (B) is because a lot of methods create Ref's to their arguments but
>> otherwise do *not* change them, so, it seems to me, I should declare
>> them const but because of (A) I cannot. Any advice on this? Is (C) the
>> best solution? Am I failing to understand the meaning of const?
>
>Sounds more like you're not entirely understanding your own design. If
>you do B, then your Ref class should never have a way to get the non-
>const pointer out of Ref. If you could, you could then write code such
>as (assuming Ref were constructable without the factory...):
>
>{
> const Object abc;
> Ref refobj(&abc);
>
> *refobj = 45; // Undefined Behavior!!!
>}
>
>At that assignment, you'd be allowing a caller to modify a const object
>via a non-const pointer. This is Undefined Behaviour and is "illegal".
Constructors are protected, so you never can instantiate a local
object and create a pointer to it - unless some derived class does it.
But hey, the code is under my control and has explicit comments: don't
do that or the whole Universe will collapse.
With your and A. Steinbach's input I'm trying to better my design.
Best regards,
G. Rodrigues
|