By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,412 Members | 1,006 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,412 IT Pros & Developers. It's quick & easy.

why does const not work on pointed objects?

P: n/a
Hi all,

There's probably a good reason why a const object can call non const
functions of the objects where it's member pointers point to.
I just don't see it. For me, that makes the the const keyword a lot less
usable.
Can anybody tell me what that good reason is?

TIA,

Corno
Jul 22 '05 #1
Share this Question
Share on Google+
20 Replies


P: n/a

"Corno" <corno@%spam%.dds.nl> wrote in message
news:c0**********@reader08.wxs.nl...
Hi all,

There's probably a good reason why a const object can call
Objects cannot 'call' anything.
Code inside a member function can indeed call other (member --
either same class or other class--- or nonmember) functions,
though. The constness of a different type object whose member
function makes the call doesn't matter at all. That's probably
incomprehensible, I know... :-)
non const
functions of the objects where it's member pointers point to.

A nonconst member function object can be called only for nonconst objects.
This 'protects' against inadvertent modification of a const object.

A const member function can be called for either const or nonconst objects.
I just don't see it. For me, that makes the the const keyword a lot less
usable.
I find it quite usable.
Can anybody tell me what that good reason is?


I cannot give a reason for something which isn't true. :-)

Perhaps you can demonstrate your questions more clear with some code?
(with appropriate accompanying comments).

-Mike
Jul 22 '05 #2

P: n/a
Corno wrote:
...
There's probably a good reason why a const object can call non const
functions of the objects where it's member pointers point to.
I just don't see it. For me, that makes the the const keyword a lot less
usable.
Can anybody tell me what that good reason is?
...


Because you are dealing with two completely unrelated objects. Would you
please clarify, why do you think that constness of one object (or of an
access path to one object) should somehow implicate constness of a
completely unrelated other object (or of an access path to other object)?

--
Best regards,
Andrey Tarasevich

Jul 22 '05 #3

P: n/a
"Corno" <corno@%spam%.dds.nl> wrote in message
news:c0**********@reader08.wxs.nl
Hi all,

There's probably a good reason why a const object can call non const
functions of the objects where it's member pointers point to.
I just don't see it. For me, that makes the the const keyword a lot
less usable.
Can anybody tell me what that good reason is?

TIA,

Corno


I suspect that you are confusing two things:

1. Whether a pointer is typed as pointing to a const object.
2. Whether a pointer is itself const.

In case 1, you cannot use the pointer to modify what is pointed to (i.e.,
you cannot change the object at the memory address contained in the
pointer). In case 2, you cannot modify the pointer itself (i.e., you cannot
change it so it points to a different memory address).

There are four possible combinations of pointer const-ness, examples of
which are given below:

// not const at all
A. TestClass * ptr;

// non-const pointer to a const object
B. const TestClass * ptr_to_const;

// const pointer to non-const object
C. TestClass * const const_ptr;

// const pointer to const object
D. const TestClass * const const_ptr_to_const;

Which category a pointer falls into depends on where the const is in
relation to the asterisk. If the const is to the left of the asterisk, that
makes it a pointer to a const object (case 1 above). If the pointer is to
the right of the asterisk, that makes it a const pointer (case 2 above).

The rules regarding these various pointer types are as follows:

Pointers to non-const objects ---- A and C above --- can be used to call
non-const member functions. However, if a object is declared to be of const
type, then a pointer to non-const objects cannot store the object's address,
i.e., an attempt to assign the address of a const object to a pointer to
non-const objects will fail to compile. Thus it is not possible to use
pointers to non-const objects to call non-const member functions on a const
object.

Pointers to const objects --- B and D above --- cannot be used to call
non-const member functions but can store the address of both const and
non-const objects.

Putting these two rules together, we see that there is no pointer that
allows you to call a non-const member function on a const object. This would
seem to be the thing that matters as far as respecting const qualifiers
goes.
--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)

Jul 22 '05 #4

P: n/a

"Andrey Tarasevich" <an**************@hotmail.com> wrote in message
news:10*************@news.supernews.com...
Corno wrote:
...
There's probably a good reason why a const object can call non const functions of the objects where it's member pointers point to.
I just don't see it. For me, that makes the the const keyword a lot less usable.
Can anybody tell me what that good reason is?
...
Because you are dealing with two completely unrelated objects. Would

you please clarify, why do you think that constness of one object (or of an access path to one object) should somehow implicate constness of a
completely unrelated other object (or of an access path to other object)?


There was recently a rather heated argument about this issue on the
boost developers list. One participant seemed to be advocating
'deep-constness' as the desirable default behavior for pointers and
smart pointers.

See http://lists.boost.org/MailArchives/boost/msg57577.php and
following.

It was very bloody -- defintely not suitable for children. The
traditional semantics emerged victorious, at least for now ...

Jonathan
Jul 22 '05 #5

P: n/a

"Andrey Tarasevich" <an**************@hotmail.com> wrote in message
news:10*************@news.supernews.com...
Corno wrote:
...
There's probably a good reason why a const object can call non const
functions of the objects where it's member pointers point to.
I just don't see it. For me, that makes the the const keyword a lot less
usable.
Can anybody tell me what that good reason is?
...
Because you are dealing with two completely unrelated objects.


I do not agree with your statement here. The fact that one object stores a
pointer to the other already means that they are not 'completely unrelated'.
A good example is the pimpl idiom; the implementation is definately related
to the abstraction. However, as long as the implementation is not const (Imp
const * const or Imp const *) it is perfectly legal to declare a const
function in the abstraction that calls a non const function of the
implementation.

Corno
Would you
please clarify, why do you think that constness of one object (or of an
access path to one object) should somehow implicate constness of a
completely unrelated other object (or of an access path to other object)?

--
Best regards,
Andrey Tarasevich

Jul 22 '05 #6

P: n/a

"Corno" <corno@%spam%.dds.nl> wrote in message
news:c0**********@reader08.wxs.nl...

"Andrey Tarasevich" <an**************@hotmail.com> wrote in message
news:10*************@news.supernews.com...
Corno wrote:
...
There's probably a good reason why a const object can call non const
functions of the objects where it's member pointers point to.
I just don't see it. For me, that makes the the const keyword a lot less usable.
Can anybody tell me what that good reason is?
...
Because you are dealing with two completely unrelated objects.


I do not agree with your statement here. The fact that one object stores a
pointer to the other already means that they are not 'completely

unrelated'. A good example is the pimpl idiom; the implementation is definately related to the abstraction. However, as long as the implementation is not const (Imp const * const or Imp const *) it is perfectly legal to declare a const
function in the abstraction that calls a non const function of the
implementation.

Corno


I think the point is that any relationship that exists between two classes
is imposed by you. Since you are writing the code it is your responsibility
to get the relationship right, not the language's. In the case you quote its
not difficult.

One the other hand if the rule you want existed in C++, then it might reduce
the chances of trivial error in the pimpl idiom, but it would also
considerable reduce the flexibility of the language for programs which have
more loosely related objects.

E.g.

class Block
{
public:
void move_to(int x, int y) const
{
world->move_to(this, x, y);
}
private:
BlockWorld * world;
};

class BlockWorld
{
public:
void move_to(Block *, int x, int y);
};

Blocks don't hold their position, a blocks position is not part of its
identity, therefore Block::move_to is quite reasonably a const member
function. However there is a BlockWorld object which maintains a list of
blocks and their positions, obviously BlockWorld::move_to cannot be a const
function.

john
Jul 22 '05 #7

P: n/a
> I suspect that you are confusing two things:

1. Whether a pointer is typed as pointing to a const object.
2. Whether a pointer is itself const.
--snip--
Putting these two rules together, we see that there is no pointer that
allows you to call a non-const member function on a const object. This would seem to be the thing that matters as far as respecting const qualifiers
goes.

This explains about the restrictions the standard *does* impose. However, my
argument was not that the standard is too strict, but too loose.
To me it would seem logical if a const object cannot call *any* non const
member functions of pointee objects (except if the pointees are specifically
marked as 'mutable').

Corno
Jul 22 '05 #8

P: n/a
>
I think the point is that any relationship that exists between two classes
is imposed by you. Since you are writing the code it is your responsibility to get the relationship right, not the language's. In the case you quote its not difficult.
In that case you could throw out the whole const keyword;
"it's your responsibility to write correct code" ;)
One the other hand if the rule you want existed in C++, then it might reduce the chances of trivial error in the pimpl idiom, but it would also
considerable reduce the flexibility of the language for programs which have more loosely related objects.
--snip--
Blocks don't hold their position, a blocks position is not part of its
identity, therefore Block::move_to is quite reasonably a const member
function. However there is a BlockWorld object which maintains a list of
blocks and their positions, obviously BlockWorld::move_to cannot be a const function.

Like I stated in the other post; this would be a situation where you would
have to use 'mutable'.
IOW the function cannot change anything, except when explicitly stated.

Corno
Jul 22 '05 #9

P: n/a
Corno wrote:
> ...
> There's probably a good reason why a const object can call non const
> functions of the objects where it's member pointers point to.
> I just don't see it. For me, that makes the the const keyword a lot less
> usable.
> Can anybody tell me what that good reason is?
> ...


Because you are dealing with two completely unrelated objects.


I do not agree with your statement here. The fact that one object stores a
pointer to the other already means that they are not 'completely unrelated'.
A good example is the pimpl idiom; the implementation is definately related
to the abstraction. However, as long as the implementation is not const (Imp
const * const or Imp const *) it is perfectly legal to declare a const
function in the abstraction that calls a non const function of the
implementation.


At the language level storing inside an object a pointer to another
object is not an idiom, it is nothing more than one of the core language
features. This feature can be used to implement a variety of completely
different idioms. You just named one of them, which follows the concept
of 'aggregation'. Yes, in case of 'aggregation' it is perfectly logical
to propagate the constness from enclosing object to the aggregated
object. However, there are many other idioms that can be implemented
using such a pointer. For example, a concept of 'object reference'
(which is not an 'aggregation') does not imply that the constness should
be propagated.

At core language level C++ tries not to limit your choice of programing
idioms. If you are trying to implement an idiom that needs
const-propagation for pointer-based aggregation - implement this
propagation yourself. For example, when implementing pimpl idiom refrain
from accessing the implementation pointer directly. Provide a pair of
accessor functions and use them instead

class Interface
{
...
private:
Implementation* pimpl;
Implementation* get_impl() { return pimpl; }
const Implementation* get_impl() const { return pimpl; }
};

That way you'll achieve the desired const-propagation effect.

--
Best regards,
Andrey Tarasevich

Jul 22 '05 #10

P: n/a
Andrey Tarasevich <an**************@hotmail.com> wrote in message news:<10*************@news.supernews.com>...
Corno wrote:
...
There's probably a good reason why a const object can call non const
functions of the objects where it's member pointers point to.
I just don't see it. For me, that makes the the const keyword a lot less
usable.
Can anybody tell me what that good reason is?
...


Because you are dealing with two completely unrelated objects. Would you
please clarify, why do you think that constness of one object (or of an
access path to one object) should somehow implicate constness of a
completely unrelated other object (or of an access path to other object)?


I assume the OP is referring to something like the following:

#include <string>

struct foo
{
void bar() const
{
data = "hello"; // not allowed
}
std::string data;
};

struct foo2
{
void bar() const
{
*data = "hello"; // allowed
}
std::string* data;
};

In which case, I assume the OP's point is that the fact that 'data' is
held via a pointer makes it no less part of the object's data, so why
should you get non-const access to it from a const member function?
It basically makes constness useless with something like the pimpl
idiom, for instance. The problem is that, as you say, in some cases
the data member pointer may not point to data that is instrinsically
part of the class, in which case the current rules make sense.
There is, of course, a solution: wrap the pointer up in a class
specifically designed to handle this (*not* std::auto_ptr<>, btw):

struct string_ptr
{
/* constructor/destructor presumably to new/delete ptr */
std::string& operator* () { return *ptr; }
const std::string& operator* () const { return *ptr; }
private:
std::string* ptr;
};

struct foo3
{
void bar() const
{
*data = "hello"; // not allowed
}
void bar()
{
*data = "hello"; // allowed
}
string_ptr data;
};
Dylan
Jul 22 '05 #11

P: n/a
> If you are trying to implement an idiom that needs
const-propagation for pointer-based aggregation - implement this
propagation yourself. For example, when implementing pimpl idiom refrain
from accessing the implementation pointer directly. Provide a pair of
accessor functions and use them instead

class Interface
{
...
private:
Implementation* pimpl;
Implementation* get_impl() { return pimpl; }
const Implementation* get_impl() const { return pimpl; }
};

That way you'll achieve the desired const-propagation effect.

Interesting approach, thanks!

Corno
Jul 22 '05 #12

P: n/a

"Corno" <corno@%spam%.dds.nl> wrote in message
news:c0**********@reader08.wxs.nl...

I think the point is that any relationship that exists between two classes is imposed by you. Since you are writing the code it is your responsibility
to get the relationship right, not the language's. In the case you quote

its
not difficult.

In that case you could throw out the whole const keyword;
"it's your responsibility to write correct code" ;)


Not at all. Which functions are const is visible to the user. The internal
pointers of your class are not. That's the whole point.
One the other hand if the rule you want existed in C++, then it might reduce
the chances of trivial error in the pimpl idiom, but it would also
considerable reduce the flexibility of the language for programs which

have
more loosely related objects.

--snip--

Blocks don't hold their position, a blocks position is not part of its
identity, therefore Block::move_to is quite reasonably a const member
function. However there is a BlockWorld object which maintains a list of
blocks and their positions, obviously BlockWorld::move_to cannot be a

const
function.

Like I stated in the other post; this would be a situation where you would
have to use 'mutable'.
IOW the function cannot change anything, except when explicitly stated.


I see mutable as being used for cached values and the like, not for
expressing the relationship between classes, which is far too complex to be
captured in a single concept like mutable. Just attend some OO design
classes if you don't believe me!
Corno


john
Jul 22 '05 #13

P: n/a
> I assume the OP is referring to something like the following:

#include <string>

struct foo
{
void bar() const
{
data = "hello"; // not allowed
}
std::string data;
};

struct foo2
{
void bar() const
{
*data = "hello"; // allowed
}
std::string* data;
};

In which case, I assume the OP's point is that the fact that 'data' is
held via a pointer makes it no less part of the object's data, so why
should you get non-const access to it from a const member function?


so the value of using const in a public member function of a class (it's
interface) is changed for me.
It's no guarantee to the user that nothing will change; it imposes a IMHO
strange restriction on the implementation; a part of the related data of an
instance, eg, only the direct member data is not allowed to change. But as
the example above shows, the same behaviour of the class can be implemented
in another way (which is not a hack to me) that is not hindered by const.
The only thing it does is that it creates 2 interfaces to the same class, it
makes a distinction between all users into 2 groups; users that have full
access to all the member functions and users that can only use the const
functions (either or not really const).

Corno
Jul 22 '05 #14

P: n/a

I see mutable as being used for cached values and the like, not for
expressing the relationship between classes, which is far too complex to be captured in a single concept like mutable. Just attend some OO design
classes if you don't believe me!

You are correct, 'mutable' is not an elegant 'keyword' for such a situation
However, backtracking on your previous example about the Block not being
mutated when moved;
I would have to disagree. To me, moving the block mutates it as well so the
function should not be const.
For me, it would be more logical if 'const' would guarantee that it would
not change the state of the 'model'.

Corno
Jul 22 '05 #15

P: n/a
Corno wrote:
I assume the OP is referring to something like the following:

#include <string>

struct foo
{
void bar() const
{
data = "hello"; // not allowed
}
std::string data;
};

struct foo2
{
void bar() const
{
*data = "hello"; // allowed
}
std::string* data;
};

In which case, I assume the OP's point is that the fact that 'data' is
held via a pointer makes it no less part of the object's data, so why
should you get non-const access to it from a const member function?

so the value of using const in a public member function of a class (it's
interface) is changed for me.


Then you had it wrong all along. The language never guaranteed that
const objects wouldn't change. The "const" keyword is mostly a hint
from one programmer to another that an object may be treated as though
it will not change. The language does not enforce const-ness.
It's no guarantee to the user that nothing will change; it imposes a IMHO
strange restriction on the implementation; a part of the related data of an
instance, eg, only the direct member data is not allowed to change. But as
the example above shows, the same behaviour of the class can be implemented
in another way (which is not a hack to me) that is not hindered by const.
The only thing it does is that it creates 2 interfaces to the same class,
They're not the same class.
it
makes a distinction between all users into 2 groups; users that have full
access to all the member functions and users that can only use the const
functions (either or not really const).


Nonsense. The functionality you want is easily implemented per Dylan's
excellent suggestion.

If it didn't sound so stupid, I'd pull out one of those platitudes about
"the spirit of the language." ;)

Jul 22 '05 #16

P: n/a
>
Then you had it wrong all along. The language never guaranteed that
const objects wouldn't change. The "const" keyword is mostly a hint
from one programmer to another that an object may be treated as though
it will not change. The language does not enforce const-ness.


Thank you for this information, that makes things a bit more clear!

Corno

Jul 22 '05 #17

P: n/a
"Corno" <corno@%spam%.dds.nl> wrote in message news:<c0**********@reader08.wxs.nl>...

I think the point is that any relationship that exists between two classes
is imposed by you. Since you are writing the code it is your

responsibility
to get the relationship right, not the language's. In the case you quote

its
not difficult.

In that case you could throw out the whole const keyword;
"it's your responsibility to write correct code" ;)


Some of us don't have vast quantities of RAM like PC coders have
though... tables are customarily declared const so they can go into
ROM instead of chewing up precious RAM. Of course this also makes
"mutable" a sore point at runtime :-)
Jul 22 '05 #18

P: n/a
On Tue, 10 Feb 2004 07:22:25 -0500, Jeff Schwab <je******@comcast.net>
wrote:
so the value of using const in a public member function of a class (it's
interface) is changed for me.


Then you had it wrong all along. The language never guaranteed that
const objects wouldn't change. The "const" keyword is mostly a hint
from one programmer to another that an object may be treated as though
it will not change. The language does not enforce const-ness.


The language enforces const-correctness for a reasonably logical
definition of that concept (ignoring const_cast and mutable for now).

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #19

P: n/a

"Corno" <corno@%spam%.dds.nl> wrote in message
news:c0**********@reader08.wxs.nl...

I see mutable as being used for cached values and the like, not for
expressing the relationship between classes, which is far too complex to be
captured in a single concept like mutable. Just attend some OO design
classes if you don't believe me!

You are correct, 'mutable' is not an elegant 'keyword' for such a

situation However, backtracking on your previous example about the Block not being
mutated when moved;
I would have to disagree. To me, moving the block mutates it as well so the function should not be const.
For me, it would be more logical if 'const' would guarantee that it would
not change the state of the 'model'.

Corno


So you see const as pertaining to the entire world being modelled not to the
individual object? Its a point of view, but I don't think you're going to
find much agreement.

You're seeing object relationships entirely in terms of what is called
aggregation (by some people, the terminology varies). The fact that one
object has a pointer to another object is just an implementation detail
(like your pimpl example). The pointer and the pointee are really one
conceptual object, living and dieing and being const together.

Nothing wrong with aggregation but object relationships can be more complex
and more subtle.

john
Jul 22 '05 #20

P: n/a
tom_usenet wrote:
On Tue, 10 Feb 2004 07:22:25 -0500, Jeff Schwab <je******@comcast.net>
wrote:

so the value of using const in a public member function of a class (it's
interface) is changed for me.


Then you had it wrong all along. The language never guaranteed that
const objects wouldn't change. The "const" keyword is mostly a hint

from one programmer to another that an object may be treated as though

it will not change. The language does not enforce const-ness.

The language enforces const-correctness for a reasonably logical
definition of that concept (ignoring const_cast and mutable for now).


Agreed. Changing the definition of that concept, e.g. to provide "deep
constness" by default (as the OP suggested), would risk the loss of the
"reasonably logical" property. I won't say that other definitions would
be "wrong," just different in a potentially misleading way.

Jul 22 '05 #21

This discussion thread is closed

Replies have been disabled for this discussion.