Casting Away Constness

T

Trevor Lango

I want to be able to cast away the constness of a private member variable in
a member function of a class.

I have the private data member declared as follows:

const double x;

I have an overloaded assignment operator implemented as follows:

Point &Point::eek:perator=( const Point *somePoint )
{
*( ( double * ) &x ) = somePoint->x;
}

Although the above compiles, I thought the newer more acceptable way to
accomplish this was using const_cast; however, I seem to not understand how
to implement const_cast. I tried the following:

const_cast< Point * >( this )->x = somePoint->x;

But this returns the following compiler error:

point.cpp: In method `class Point & Point::eek:perator =(const Point *)':
point.cpp:58: assignment of read-only member `Point::x'

Can someone please enlighten me as to the proper use of const_cast to cast
away constness? Thanks in advance (and please excuse me if this has been
discussed already; I just subscribed to this newsgroup and searched as far
back as I could, but I couldn't find any mention of const_cast).
 
J

Jeff Schwab

Trevor said:
I want to be able to cast away the constness of a private member variable in
a member function of a class.

Are you familiar with the "mutable" keword?
I have the private data member declared as follows:

const double x;

Why did you declare it const, if you knew you were going to change it?
I have an overloaded assignment operator implemented as follows:

Point &Point::eek:perator=( const Point *somePoint )
{
*( ( double * ) &x ) = somePoint->x;
}

Although the above compiles, I thought the newer more acceptable way to
accomplish this was using const_cast; however, I seem to not understand how
to implement const_cast. I tried the following:

const_cast< Point * >( this )->x = somePoint->x;

But this returns the following compiler error:

point.cpp: In method `class Point & Point::eek:perator =(const Point *)':
point.cpp:58: assignment of read-only member `Point::x'

You "unconsted" the Point object. The member "x" was const for a
different reason, namely because you declared it thus.
Can someone please enlighten me as to the proper use of const_cast to cast
away constness?

const_cast< double >( x ) = somePoint->x;

If you find yourself needing const cast, there is an inconsistency
somewhere in your program. If you understand what the inconsistency is,
and you're OK with it, you still might consider a mutable member as an
alternative to the cast.
Thanks in advance (and please excuse me if this has been
discussed already; I just subscribed to this newsgroup and searched as far
back as I could, but I couldn't find any mention of const_cast).

Welcome!

-Jeff
 
J

Jeff Schwab

Jeff said:
Are you familiar with the "mutable" keyword?


Why did you declare it const, if you knew you were going to change it?



You "unconsted" the Point object. The member "x" was const for a
different reason, namely because you declared it thus.



const_cast< double >( x ) = somePoint->x;

Sorry, that should say:

const_cast< double >( x ) = somePoint->x;

Btw, const_cast is not guaranteed to work. You may get a silent error
at run time. Try making the member mutable, or at least not declaring
it const.
 
V

Victor Bazarov

Trevor Lango said:
I want to be able to cast away the constness of a private member variable in
a member function of a class.

I have the private data member declared as follows:

const double x;

Why const?
I have an overloaded assignment operator implemented as follows:

Point &Point::eek:perator=( const Point *somePoint )

Why are you assigning from a pointer? One rather strange assignment op.
Well, no matter...
{
*( ( double * ) &x ) = somePoint->x;

Simpler would be

(double&) x = somePoint->x;
}

Although the above compiles, I thought the newer more acceptable way to
accomplish this was using const_cast; however, I seem to not understand how
to implement const_cast. I tried the following:

const_cast< Point * >( this )->x = somePoint->x;

But this returns the following compiler error:

point.cpp: In method `class Point & Point::eek:perator =(const Point *)':
point.cpp:58: assignment of read-only member `Point::x'

You cast away constness of the object itself, which is (a) unneeded because
the object is already non-const and (b) doesn't affect the const-ness of
a member declared explicitly const.

You _could_ do

const_cast<double&>(x) = somePoint->x;

But still, you have to answer this question: why did you make the member
'const' in the first place?
Can someone please enlighten me as to the proper use of const_cast to cast
away constness?

I think you need some enlightment as to proper use of const before you
attempt using const_cast... But that's just the impression I get.
Thanks in advance (and please excuse me if this has been
discussed already; I just subscribed to this newsgroup and searched as far
back as I could, but I couldn't find any mention of const_cast).

Casting away const-ness is not what you should be doing casually. In
most cases if you cast away const-ness, you _must_ be sure that the
original object _was_ declared/defined as non-const, otherwise UB occurs.

Victor
 
J

Jeff Schwab

Ron said:
He might be, but it wouldn't help. He has a const member in a non-const object
he wishes to change. Mutable would allow him to change a member in a CONST
object.

Yes, not declaring the member "const" in the first place certainly would
help. :)
 
R

Ron Natalie

Trevor Lango said:
I want to be able to cast away the constness of a private member variable in
const_cast< Point * >( this )->x = somePoint->x;
*const_cast<Point*>(&x) = somePoint->x;
or
const_cast<Point&>(x) = somePoint->x;
 
R

Ron Natalie

Trevor Lango said:
I want to be able to cast away the constness of a private member variable in
a member function of a class.

I have the private data member declared as follows:

const double x;

I have an overloaded assignment operator implemented as follows:

Point &Point::eek:perator=( const Point *somePoint )
{
*( ( double * ) &x ) = somePoint->x;
}
Oops, I got confused before:
*const_cast<double*>(&x) = somePoint->x;
or
const_cast<double&>(x) = somePoint->x
 
R

Ron Natalie

Jeff Schwab said:
Are you familiar with the "mutable" keword?

He might be, but it wouldn't help. He has a const member in a non-const object
he wishes to change. Mutable would allow him to change a member in a CONST
object.
 
T

Trevor Lango

Jeff Schwab said:
Are you familiar with the "mutable" keword?

I thought the mutable keyword was for allowing modification of private
member variables in class objects declared as const...?
Why did you declare it const, if you knew you were going to change it?

I didn't want anything to be able to modify it except for the overloaded
assignment operator.

[snipped for readability]
 
J

Jeff Schwab

Trevor said:
variable in



I thought the mutable keyword was for allowing modification of private
member variables in class objects declared as const...?

Exactly. You were casting away the constness of the object just long
enough to modify a member variable. That's exactly the sort of cast
"mutable" was meant to help you avoid.
I didn't want anything to be able to modify it except for the overloaded
assignment operator.

Hmmm... I'm not sure of a way to make that sort of guarantee, although
I do see what you mean.
[snipped for readability]
 
T

Trevor Lango

Jeff Schwab said:
Yes, not declaring the member "const" in the first place certainly would
help. :)

After some further thought I do not believe I will implement those private
member variables as const. However, I do appreciate the clarification of the
proper syntax for implementing const_cast. For those of you who posted the
appropriate syntax, can you please cite what documentation you referenced to
provide your answers? Thanks!
 
J

Jeff Schwab

Ron said:
That loks the same to me, you mean
const_cast<double&>(x) = somePoint->x;

Right, thank you.
There's no point in making it mutable. The member function he is running
is not CONST, hence the member is wouldn't be const if he didn't explicitly
make it so.

Since the OP has explained further, I agree. He wasn't actually casting
away the constness of the variable though, he was casting away the
constness of the object. I was offering mutable as a suggestion to
achieve a similar effect, much as you suggested this:

const_cast<Point&>(x) = somePoint->x;
 
R

Ron Natalie

Jeff Schwab said:
Sorry, that should say:

const_cast< double >( x ) = somePoint->x;
That loks the same to me, you mean
const_cast said:
Btw, const_cast is not guaranteed to work. You may get a silent error
at run time. Try making the member mutable, or at least not declaring
it const.

There's no point in making it mutable. The member function he is running
is not CONST, hence the member is wouldn't be const if he didn't explicitly
make it so.
 
R

Ron Natalie

Jeff Schwab said:
Exactly. You were casting away the constness of the object just long
enough to modify a member variable. That's exactly the sort of cast
"mutable" was meant to help you avoid.

The object wasn't const. The member was.
 
R

Ron Natalie

Trevor Lango said:
After some further thought I do not believe I will implement those private
member variables as const. However, I do appreciate the clarification of the
proper syntax for implementing const_cast. For those of you who posted the
appropriate syntax, can you please cite what documentation you referenced to
provide your answers? Thanks!
I didn't have to reference anything. If you spend several years actually writing
code you know these things :)

5.2.11 of the standard pretty nicely explains this (and points you to the section
that warns you that what you're doing is undefined).
 
R

Ron Natalie

Jeff Schwab said:
Since the OP has explained further, I agree. He wasn't actually casting
away the constness of the variable though, he was casting away the
constness of the object. I was offering mutable as a suggestion to
achieve a similar effect, much as you suggested this:

const_cast<Point&>(x) = somePoint->x;
Which was wrong. I meant double above. The Point object wasn't
const (as it was in a non-const method).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,085
Latest member
cryptooseoagencies

Latest Threads

Top