constness through boost smart pointers

3 visninger
Gå til det første ulæste indlæg

Thorsten Ottosen

ulæst,
21. jun. 2002 19.57.1621.06.2002
til
I've been using the Pimpl idiom on the last semester using a
boost::shared_ptr<> to
hold the pimpl. A thing that irritated me was that constness of a routine
did not
propagate to the pimpl because boost::shared_ptr's operator->() returns a
T*:

template<typename T> class shared_ptr {
...
T * operator->() const; // never throws
};

This will allow this code to compile although (IMO) it is not supposed to:

struct Int
{
int i;
void foo() { i++; }
};

class C
{
boost::shared_ptr<Int> p_;
public:
C() : p_( new Int ) { }
void can_modify() { p_->foo(); }
void can_also() const { p_->foo(); } // breaks constness contract
};

Am I right that this is undesired behavior? If so, would this extension to
the smart pointer
not work:

template<typename T> class shared_ptr {
...
const T * operator->() const; // disallows a call to non-const functions via
return value
T* operator->();
};

? Are there any drawbacks to this? If not, should one not do the same with
operator*()?

Thorsten Ottosen
nes...@cs.auc.dk

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]

Peter Koch Larsen

ulæst,
22. jun. 2002 13.35.2722.06.2002
til
"Thorsten Ottosen" <nes...@cs.auc.dk> wrote in message news:<af02g3$i88$1...@sunsite.dk>...

> I've been using the Pimpl idiom on the last semester using a
> boost::shared_ptr<> to
> hold the pimpl. A thing that irritated me was that constness of a routine
> did not
> propagate to the pimpl because boost::shared_ptr's operator->() returns a
> T*:
[snip]

> Am I right that this is undesired behavior? If so, would this extension to
> the smart pointer
> not work:
>
> template<typename T> class shared_ptr {
> ...
> const T * operator->() const; // disallows a call to non-const functions via
> return value
> T* operator->();
> };

I believe this extension is feasible.


>
> ? Are there any drawbacks to this? If not, should one not do the same with
> operator*()?

No drawbacks, so far as i can tell. And yes - one should do the same
thing with operator *().

Hi Thorsten

You have come up with a typical "handle" problem. The real object is
accessed via some handle, e.g. a pointer, a filehandle or some
socket-identifying integer. The problem with these objects is that all
interfaces will be const, since it is the handle and not the object
itself, that is accessed. In those situation, i propagate the
constness of the underlying object through the interface, and i
believe this is the correct thing to do - also for the boost-pointers.

Kind regards
Peter

Damien

ulæst,
24. jun. 2002 06.58.3024.06.2002
til
"Thorsten Ottosen" <nes...@cs.auc.dk> wrote in message news:<af02g3$i88$1...@sunsite.dk>...
> Am I right that this is undesired behavior? If so, would this extension to
> the smart pointer
> not work:
>
> template<typename T> class shared_ptr {
> ...
> const T * operator->() const; // disallows a call to non-const functions via
> return value
> T* operator->();
> };
>
> ? Are there any drawbacks to this? If not, should one not do the same with
> operator*()?

I don't think this would be appropriate for shared_ptr, as its
semantics should model those of a normal pointer closely. If you have
a T * const (analogous to a const shared_ptr<T>), then you can still
call non-const members of T through it, so why should you not be able
to do that through a shared_ptr?

You may find it useful to define a separate class has your desired
semantics, but adding the overloads you suggest to shared_ptr would
break its interface compatability with raw pointers in undesirable
ways (IMHO).

Peter Dimov

ulæst,
24. jun. 2002 11.48.4324.06.2002
til
"Thorsten Ottosen" <nes...@cs.auc.dk> wrote in message news:<af02g3$i88$1...@sunsite.dk>...
> I've been using the Pimpl idiom on the last semester using a
> boost::shared_ptr<> to
> hold the pimpl. A thing that irritated me was that constness of a routine
> did not
> propagate to the pimpl because boost::shared_ptr's operator->() returns a
> T*:

Consistent with 'ordinary' pointers.

int * const p; // p is const, *p is not
shared_ptr<int> const p; // ditto

int const * p; // p is not const, *p is
shared_ptr<int const> p; // ditto

[...]

> template<typename T> class shared_ptr {
> ...
> const T * operator->() const; // disallows a call to non-const functions via
> return value
> T* operator->();
> };
>
> ? Are there any drawbacks to this? If not, should one not do the same with
> operator*()?

You are right that there are legitimate cases where you want
const-ness to propagate from the pointer to the pointee (as it does
with arrays, for example.)

But a very significant drawback of applying this change to shared_ptr
is that there are legitimate cases where you don't need this behavior,
and want shared_ptr to behave like a raw pointer WRT const-ness. A
single pointer can't please everybody.

You can either ignore the problem and pay attention to logical
constness (just like you'd do if you used a raw pointer), or wrap
shared_ptr in your own smart pointer class that provides the 'proper'
accessors for your situation.

Thorsten Ottosen

ulæst,
24. jun. 2002 12.07.2224.06.2002
til

"Damien" <dirt...@hotmail.com> wrote in message
news:f83f6408.02062...@posting.google.com...

> "Thorsten Ottosen" <nes...@cs.auc.dk> wrote in message
news:<af02g3$i88$1...@sunsite.dk>...
> > Am I right that this is undesired behavior? If so, would this extension
to
> > the smart pointer
> > not work:
> >
> > template<typename T> class shared_ptr {
> > ...
> > const T * operator->() const; // disallows a call to non-const
functions via
> > return value
> > T* operator->();
> > };
> >
> > ? Are there any drawbacks to this? If not, should one not do the same
with
> > operator*()?
>
> I don't think this would be appropriate for shared_ptr, as its
> semantics should model those of a normal pointer closely. If you have
> a T * const (analogous to a const shared_ptr<T>), then you can still
> call non-const members of T through it,

I find that highly undesireble. We could use the smart pointers to
clean up this problem elegantly.

> so why should you not be able
> to do that through a shared_ptr?

Because it breaks the contract of the interface. I can have declared
a function const, but it might modify the state of the object without
even a compiler warning. It kind of removes the usefulness of const.

> You may find it useful to define a separate class has your desired
> semantics, but adding the overloads you suggest to shared_ptr would
> break its interface compatability with raw pointers in undesirable
> ways (IMHO).

I'm not a fan of defining my own smart-pointer :) I wish the
library smart-pointers were smart enough to propagte
constness.

Thorsten
nes...@cs.auc.dk

Nikolai.Pret...@sun.com

ulæst,
26. jun. 2002 07.20.2426.06.2002
til
Hi,

> Consistent with 'ordinary' pointers.

> [...]

Well, I agree partly, but not completely.

First, if I would like to use a raw pointer, I could use a raw pointer.
But if I use a class instead, I wish an elaborated
behaviour. So – mirroring raw pointers' behaviour can't be a reason for
itself.

I would ask: What is the intended use of boost::shared_ptr<> ?
In the context of the pimpl-idiom or in any other context, where the
pointer is a
member of a class, I think it would be only consistent with good C++
engineering
practice to require it to propagate constness.

If boost::shared_ptr<> only rarely is used as a non-member, IMHO it should
have a member function like
T * mutable_ptr() const; or
T * const_cast_ptr() const;
which would allow to go round the const-transitive behaviour for those
rare cases,
where const-ness should not be transitive.


Regards,

Nikolai

Dave Harris

ulæst,
26. jun. 2002 14.13.3826.06.2002
til
Nikolai.Pret...@sun.com () wrote (abridged):

> I would ask: What is the intended use of boost::shared_ptr<> ?
> In the context of the pimpl-idiom or in any other context, where the
> pointer is a member of a class, I think it would be only consistent
> with good C++ engineering practice to require it to propagate
> constness.

This is true if the pointer represents "part of". If A is part of B, A
will be const whenever B is const. However, if B merely uses A, then B
being const need not mean A is const. They are more independent. So if the
pointer represents "uses", const shouldn't propagate.

I agree that with the pimpl idiom, the pointer represents "part of" so
should propagate const. However, wouldn't you be better off using
scoped_ptr for that? Not that scoped_ptr propagates const either, but the
argument for it doing so is compelling in my view.

Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
bran...@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."

Albrecht Fritzsche

ulæst,
26. jun. 2002 16.28.5126.06.2002
til
Peter Dimov wrote:
>
> You are right that there are legitimate cases where you want
> const-ness to propagate from the pointer to the pointee (as it does
> with arrays, for example.)
>
> But a very significant drawback of applying this change to shared_ptr
> is that there are legitimate cases where you don't need this behavior,
> and want shared_ptr to behave like a raw pointer WRT const-ness. A
> single pointer can't please everybody.

Isn't this a behaviour shouting for policies?

Ali
--
albrecht fritzsche
ableton, schönhauser allee 6/7
10119 berlin germany
http://www.ableton.com

Attila Feher

ulæst,
27. jun. 2002 05.09.1927.06.2002
til
Dave Harris wrote:
>
> Nikolai.Pret...@sun.com () wrote (abridged):
> > I would ask: What is the intended use of boost::shared_ptr<> ?
> > In the context of the pimpl-idiom or in any other context, where the
> > pointer is a member of a class, I think it would be only consistent
> > with good C++ engineering practice to require it to propagate
> > constness.
>
> This is true if the pointer represents "part of". If A is part of B, A
> will be const whenever B is const. However, if B merely uses A, then B
> being const need not mean A is const. They are more independent. So if the
> pointer represents "uses", const shouldn't propagate.
[SNIP]

Doesn't a smart pointer always represent a part-of relation? It may be
a "shared part", but it is still a part of the class. If it would not
be, one would find different means to ensure the lifetime of the pointee
instead of taking shared _ownership_ of it. Isn't it so? I believe
that this is a design dilemma. If the design is good enough, it ensures
that the not-owned-but-used object is always there, in which case one
can use reference to it (if one is brave enough) or of course the good
ol' pointer, in case the "thing" is optional or should be changed after
construction. Of course, if this design goes wrong, the shared_ptr can
ensure that the pointee stays around as long as the user. But the user
is still a user... not an owner - its ownership status is just a hack to
avoid using deleted memory. :-(

Attila

Nikolai Pretzell

ulæst,
27. jun. 2002 10.39.1127.06.2002
til
Hi,

## N.Pretzell wrote


> > I would ask: What is the intended use of boost::shared_ptr<> ?
> > In the context of the pimpl-idiom or in any other context, where the
> > pointer is a member of a class, I think it would be only consistent
> > with good C++ engineering practice to require it to propagate
> > constness.

# D.Harris wrote


> This is true if the pointer represents "part of". If A is part of B, A
> will be const whenever B is const. However, if B merely uses A, then B
> being const need not mean A is const. They are more independent. So if
the
> pointer represents "uses", const shouldn't propagate.

> I agree that with the pimpl idiom, the pointer represents "part of" so
> should propagate const. However, wouldn't you be better off using
> scoped_ptr for that?

Yes, my sight was too narrow, because I came into the discussion, when
shared_ptr was suggested for the pimpl idiom.

Of course, for owned („part of“) members scoped_ptr is the better
alternative. Whereas shared_ptr typically is used by several clients and
such probably not owned by any of them particularly.

> Not that scoped_ptr propagates const either, but the
> argument for it doing so is compelling in my view.

I agree. That is the reason I (and some of my colleagues) don't use it,
but a self-made class which is exactly the same (including being not
copyable), except of it propagating constness and the get() method is
named different.

Are there thoughts to add a new class to the boost-library or change the
interface of scoped_ptr?
I'd suggest something like this interface:

#begin code
template<typename T>
class member_ptr : private noncopyable
{
public:
typedef T element_type;

explicit member_ptr(T * p = 0); // never throws
~member_ptr(); // never throws

void reset(T * p = 0); // never throws

const T & operator*() const; // never throws
const T * operator->() const; // never throws

T & operator*(); // never throws
T * operator->(); // never throws

T * get_mutable() const; // never throws

void swap(member_ptr & b); // never throws
};
};

// The same respectively for member_array.

#end code
Actually, in its present version I can imagine only very rare cases to
use boost::scoped_ptr, if I would have an alternative similar to the
above.

Regards,

Nikolai

--
Nikolai Pretzell
Software Engineer Development Tools
Star Office Gmbh, D - Hamburg

Peter Dimov

ulæst,
27. jun. 2002 10.44.5027.06.2002
til
Nikolai.Pret...@sun.com wrote in message news:<20020626...@mis.configured.host>...

> > > template<typename T> class shared_ptr {
> > > ...
> > > const T * operator->() const; // disallows a call to non-const functions
> via
> > > return value
> > > T* operator->();
> > > };
> > >
> > > ? Are there any drawbacks to this? If not, should one not do the same
> with
> > > operator*()?
>
> > You are right that there are legitimate cases where you want
> > const-ness to propagate from the pointer to the pointee (as it does
> > with arrays, for example.)
>
> > But a very significant drawback of applying this change to shared_ptr
> > is that there are legitimate cases where you don't need this behavior,
> > and want shared_ptr to behave like a raw pointer WRT const-ness. A
> > single pointer can't please everybody.
>
> Well, I agree partly, but not completely.
>
> First, if I would like to use a raw pointer, I could use a raw pointer.
> But if I use a class instead, I wish an elaborated
> behaviour. So – mirroring raw pointers' behaviour can't be a reason for
> itself.
>
> I would ask: What is the intended use of boost::shared_ptr<> ?

"As close to raw pointers as possible but no closer." Or in less
cliched words, shared_ptr is intended to approximate the way a raw
pointer would act if C++ had a deterministic garbage collector, and it
aims to preserve all useful features of a raw pointer, including
conversions and incomplete types.

Separate pointer/pointee const-ness is a useful raw pointer feature.

> In the context of the pimpl-idiom or in any other context, where the
> pointer is a
> member of a class, I think it would be only consistent with good C++
> engineering
> practice to require it to propagate constness.

"HAS-A" relationships need const-ness propagated, but shared_ptr<> is
not limited to such uses.

> If boost::shared_ptr<> only rarely is used as a non-member, [...]

I don't think that this is the case. ;-)

Thorsten Ottosen

ulæst,
29. jun. 2002 05.51.2329.06.2002
til

"Peter Dimov" <pdi...@mmltd.net> wrote in message

> > I would ask: What is the intended use of boost::shared_ptr<> ?
>
> "As close to raw pointers as possible but no closer." Or in less
> cliched words, shared_ptr is intended to approximate the way a raw
> pointer would act if C++ had a deterministic garbage collector, and it
> aims to preserve all useful features of a raw pointer, including
> conversions and incomplete types.
In many ways I think 'shared_ptr' looks diffrent from a raw pointer. I have
to use 'shared_static_cast' and I cannot do

class Y;
class X public Y;
shared_ptr<Y> p( new X );
if( dynamic_cast<X>( p ) )

and the 'shared_dynamic_cast' will need a '.get()' to work because there
are no implicit conversions.

> Separate pointer/pointee const-ness is a useful raw pointer feature.

Can you give some examples?


> > In the context of the pimpl-idiom or in any other context, where the
> > pointer is a
> > member of a class, I think it would be only consistent with good C++
> > engineering
> > practice to require it to propagate constness.
>
> "HAS-A" relationships need const-ness propagated, but shared_ptr<> is
> not limited to such uses.

Why should other relationships not propagate constness? The basic argument
must
be that if member function is declared 'const', then the state of the
program (not just the object at hand) should remain constant during its
execution. Of course, one might not agree with this view on const-ness, but
then the use of 'const' cannot be important to him and this discussion is
irrelevant. Thus, I assume
that const-ness is important to everyone here.

regards

Thorsten
nes...@cs.auc.dk

Peter Dimov

ulæst,
2. jul. 2002 10.13.5102.07.2002
til
"Thorsten Ottosen" <nes...@cs.auc.dk> wrote in message news:<afijnj$n7v$1...@sunsite.dk>...

> "Peter Dimov" <pdi...@mmltd.net> wrote in message
> > > I would ask: What is the intended use of boost::shared_ptr<> ?
> >
> > "As close to raw pointers as possible but no closer." Or in less
> > cliched words, shared_ptr is intended to approximate the way a raw
> > pointer would act if C++ had a deterministic garbage collector, and it
> > aims to preserve all useful features of a raw pointer, including
> > conversions and incomplete types.
> In many ways I think 'shared_ptr' looks diffrent from a raw pointer. I have
> to use 'shared_static_cast' and I cannot do
>
> class Y;
> class X public Y;
> shared_ptr<Y> p( new X );
> if( dynamic_cast<X>( p ) )

I can't, either. static_cast/dynamic_cast are not overloadable.

> and the 'shared_dynamic_cast' will need a '.get()' to work because there
> are no implicit conversions.

It will work without the get(). There is a conversion to something bool-like.

> > Separate pointer/pointee const-ness is a useful raw pointer feature.
> Can you give some examples?

void f(shared_ptr<T> const & p)
{
p->nonConst();
}

> > "HAS-A" relationships need const-ness propagated, but shared_ptr<> is
> > not limited to such uses.
> Why should other relationships not propagate constness? The basic argument
> must
> be that if member function is declared 'const', then the state of the
> program (not just the object at hand) should remain constant during its
> execution.

Interesting view.

Thorsten Ottosen

ulæst,
2. jul. 2002 15.49.3102.07.2002
til

"Peter Dimov" <pdi...@mmltd.net> wrote in message
news:7dc3b1ea.0207...@posting.google.com...

> "Thorsten Ottosen" <nes...@cs.auc.dk> wrote in message
news:<afijnj$n7v$1...@sunsite.dk>...
>> > In many ways I think 'shared_ptr' looks diffrent from a raw pointer. I
have
> > to use 'shared_static_cast' and I cannot do
> >
> > class Y;
> > class X public Y;
> > shared_ptr<Y> p( new X );
> > if( dynamic_cast<X>( p ) )
>
> I can't, either. static_cast/dynamic_cast are not overloadable.
>
> > and the 'shared_dynamic_cast' will need a '.get()' to work because
there
> > are no implicit conversions.
>
> It will work without the get(). There is a conversion to something
bool-like.
Yep, I missed that.

> > > Separate pointer/pointee const-ness is a useful raw pointer feature.
> > Can you give some examples?
>
> void f(shared_ptr<T> const & p)
> {
> p->nonConst();
> }

I think we have a very different view on constness. Do you write code like
this often?
And what purpose do you see for the 'const' keyword if it should not be used
to preserve the
state of the program (or at least the object) during a member call (and I'm
not talking about declaring constants)?

> > > "HAS-A" relationships need const-ness propagated, but shared_ptr<>
is
> > > not limited to such uses.
> > Why should other relationships not propagate constness? The basic
argument
> > must
> > be that if member function is declared 'const', then the state of the
> > program (not just the object at hand) should remain constant during its
> > execution.
>
> Interesting view.

I would still like to know why you only consider "HAS-A" relationships?


Thorsten
nes...@cs.auc.dk

Peter Dimov

ulæst,
3. jul. 2002 15.08.5103.07.2002
til
"Thorsten Ottosen" <nes...@cs.auc.dk> wrote in message news:<afsilt$qbo$1...@sunsite.dk>...

> "Peter Dimov" <pdi...@mmltd.net> wrote in message
> news:7dc3b1ea.0207...@posting.google.com...
> > "Thorsten Ottosen" <nes...@cs.auc.dk> wrote in message
> news:<afijnj$n7v$1...@sunsite.dk>...
> >> > In many ways I think 'shared_ptr' looks diffrent from a raw pointer. I
> have
> > > to use 'shared_static_cast' and I cannot do
> > >
> > > class Y;
> > > class X public Y;
> > > shared_ptr<Y> p( new X );
> > > if( dynamic_cast<X>( p ) )
> >
> > I can't, either. static_cast/dynamic_cast are not overloadable.

... and even if they were, the syntax would have been

dynamic_cast< shared_ptr<X> >( p )

:-)

> > > > Separate pointer/pointee const-ness is a useful raw pointer feature.
> > > Can you give some examples?
> >
> > void f(shared_ptr<T> const & p)
> > {
> > p->nonConst();
> > }
> I think we have a very different view on constness.

You bet. But the problem is not that we differ, the problem is that
your view on constness is not supported by the C++ type system.

> Do you write code like this often?

What kind of code should I write instead, in your opinion?

void f(shared_ptr<T> p)
{
p->nonConst();
}

?

Or perhaps

void f(shared_ptr<T> & p)
{
p->nonConst();
}

?

What are the benefits of deliberately using a less efficient (extra
reference count updates), or less restrictive (f can assign a new
value to p), declaration?

> And what purpose do you see for the 'const' keyword if it should not be used
> to preserve the
> state of the program (or at least the object) during a member call (and I'm
> not talking about declaring constants)?

The const keyword has a well-defined meaning.

void f(X const & x, X & x2);

f can change x2, but not x.

void f(X & x, X const & x2);

f can change x, but not x2.

Members are syntactic sugar.

void X::f(X & x) const;

f can change x, but not *this.

void X::f(X const & x);

f can change *this, but not x.

The "state of the program is const whenever *this is const" view is
quite restrictive. If you had a compiler that actually enforced it, I
suspect that a lot of code would not compile. Even some of your own.

Now to our pointer problem. When a smart pointer is copied, it
performs a shallow copy or a deep copy. Raw pointers and shared_ptr do
a shallow copy, and it is appropriate for them to have separate
pointer/pointee constness; deep copy pointers, on the other hand, tend
to propagate constness. Here is why.

shallow_copy_ptr<X> const px;
shallow_copy_ptr<X> px2(px); // px and px2 are aliases

px2->nonConst(); // modifies *px! px's constness didn't stop us.

Compare with:

deep_copy_ptr<X> const px;
deep_copy_ptr<X> px2(px);

px2->nonConst(); // OK, does not modify *px, but a copy

Thorsten Ottosen

ulæst,
5. jul. 2002 06.56.5105.07.2002
til

"Peter Dimov" <pdi...@mmltd.net> wrote in message >
> > > > > Separate pointer/pointee const-ness is a useful raw pointer
feature.
> > > > Can you give some examples?
> > >
> > > void f(shared_ptr<T> const & p)
> > > {
> > > p->nonConst();
> > > }
> > I think we have a very different view on constness.
>
> You bet. But the problem is not that we differ, the problem is that
> your view on constness is not supported by the C++ type system.
Why is this particularly useful? If a want to make the pointer const, I use
a reference instead. My view on constness can at least be supported by
the compiler on composite objects such as smart pointers. I think my
example below shows that there is really no need to approximate built-in
pointers.

> > Do you write code like this often?
>
> What kind of code should I write instead, in your opinion?
>
> void f(shared_ptr<T> p)
> {
> p->nonConst();
> }
>
> ?
>
> Or perhaps
>
> void f(shared_ptr<T> & p)
> {
> p->nonConst();
> }
>
> ?
>
> What are the benefits of deliberately using a less efficient (extra
> reference count updates), or less restrictive (f can assign a new
> value to p), declaration?

I was just wanted to know if this was a real example, that is, code you
have
used in some program. If I could, I would probably prefer a signature
like this:

void f( T& t ) { t.nonConst(); }

and as a client dereference my shared_ptr when calling f.

> > And what purpose do you see for the 'const' keyword if it should not be
used
> > to preserve the
> > state of the program (or at least the object) during a member call (and
I'm
> > not talking about declaring constants)?
>
> The const keyword has a well-defined meaning.
>
> void f(X const & x, X & x2);
>
> f can change x2, but not x.
>
> void f(X & x, X const & x2);
>
> f can change x, but not x2

Again my view ( and reality ) is that this is not well-defined. x2 can
easily be changed
if it stores its state by a pointer. we might as well leave the const
out. The same goes for the member version. The contract is a potential lie.

> The "state of the program is const whenever *this is const" view is
> quite restrictive. If you had a compiler that actually enforced it, I
> suspect that a lot of code would not compile. Even some of your own.

Sure, I suspect that too, but its really not relevant. (I wish I had such a
compiler).
I don't see how this will restrict
anything (we are not talking about a search and replace of pointers with
shared_ptrs in a working
program that handles its resources the "old" way). If shared_ptr had
supported propagation of constness, I can uphold that constness
contract throughout the development. I don't mind if built-in pointers
don't work as the shared_ptr and I don't see why it should. As we already
seen, they are not compatible anyway.
. I would still like to see a really useful case were one could not do
without this " important feature".

> Now to our pointer problem. When a smart pointer is copied, it
> performs a shallow copy or a deep copy. Raw pointers and shared_ptr do
> a shallow copy, and it is appropriate for them to have separate
> pointer/pointee constness; deep copy pointers, on the other hand, tend
> to propagate constness.

I would say
this has nothing to with our discussion. The real issue is still to restrict
const
methods from changing the object. If program state is changed, I want to be
the one who
does it, it should not happen implicitly and especially not when I'm not
expecting it.
So the example above is actually misplaced in this discussion.

regards

-Thorsten
nes...@cs.auc.dk

Svar alle
Svar forfatteren
Videresend
0 nye indlæg