|
-
April 6th, 2005, 03:44 AM
#16
Re: Can operator= assign const member?
Good grief. I was playing about trying to make sense of the relevant section in the standard (5.2.11), and I got the process to work, so I thought I'd let people know. I didn't expect the Spanish Inquisition... 
And yes, the swap trick is about exception safety. I could have simplified the code, but I routinely write my assignment operators that way, so that's how it got written. If you can't see why it's exception safe, then I suggest you read Exceptional C++ for all the gory details.
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
April 6th, 2005, 04:29 AM
#17
Re: Can operator= assign const member?
 Originally Posted by darwen
You could use the 'mutable' keyword on your const member. It only works for members though.
Are you sure that you can use 'const' and 'mutable' specifiers on same data-member of class?
Code:
class See
{
mutable const x;
};
 Originally Posted by VC6 Compiler
e:\ajay....(98) : error C2071: 'x' : illegal storage class
 Originally Posted by VC7.1 Compiler
e:\Ajay\...(98) : error C2071: 'See::x' : illegal storage class
-
April 6th, 2005, 04:53 AM
#18
Re: Can operator= assign const member?
 Originally Posted by Graham
I didn't expect the Spanish Inquisition... 
Nobody expects the Spanish Inquisition!
Insert entertaining phrase here
-
April 6th, 2005, 05:58 AM
#19
Re: Can operator= assign const member?
 Originally Posted by Ajay Vijay
Are you sure that you can use 'const' and 'mutable' specifiers on same data-member of class?
No. Either const or mutable. "Mutable" means that a data member may be changed on a const object -- this is not quite related to the current thread. Suppose you have a polygon class with a const getter GetSurface(). The getter computes the surface and caches it in a data member prior returning it. Now it makes sense to have that data member 'mutable', to allow a 'const polygon' to cache. Semantically the mutable member shall not be part of the visible state of the object.
-
April 6th, 2005, 06:01 AM
#20
Re: Can operator= assign const member?
Thanks Gabriel, I am quite aware of that technique. My post was with the text posted by Graham:
 Originally Posted by Graham
You could use the 'mutable' keyword on your const member...
-
April 6th, 2005, 06:33 AM
#21
Re: Can operator= assign const member?
If one starts to add keywords like mutable to the members why not remove the const all together?
The problem I see with this is that the assignment operator breaks the semantics of the const variable.
If you want to support assignment then the member variable shouldn't be const.
Now, you might not have control over the source code and in that case I think const_cast will work fine in most cases (together with a comment why the const_cast is there).
There is a risk with modern compilers that they place const variables in protected memory but I haven't run into that myself yet.
If you want to use const to protect against accidental modification (a noble cause) then I would consider making a template wrapper class that doesn't allow modifcation but do allow swapping and copy construction (with a non-throwing swap and a copy-construction one can as demonstrated above implement assignment)
Then there is the possibility to disallow assignment and use smart pointers.
So in order to be able to offer a better advise I think the OP should provide more background information.
-
April 6th, 2005, 08:32 AM
#22
Re: Can operator= assign const member?
Ajay: I never said that...
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
April 6th, 2005, 08:51 AM
#23
Re: Can operator= assign const member?
Hi Graham - you're not getting the Spanish Inquisition from me! I appreciate all the input and am happy to have learned the swap construct. I'll add that book to my reading list.
-
April 6th, 2005, 09:32 AM
#24
Re: Can operator= assign const member?
I think that Graham tends to "get the Spanish Inquisition" because many people can't wait to "catch" him making a mistake. That, because he very rarely makes any...
-
April 6th, 2005, 09:49 AM
#25
Re: Can operator= assign const member?
n.marier: If you're interested in exception safety the book 'Exceptional C++' (http://www.gotw.ca/publications/xc++.htm) goes into great depths to explain why and how some common techniques (such as implementing assignment as copy-and-swap) works.
Plus much more.
It's an "exceptional" book.
Last edited by marten_range; April 6th, 2005 at 09:50 AM.
Reason: Clarification
-
April 6th, 2005, 10:07 AM
#26
Re: Can operator= assign const member?
Not that anyone cares, but terrashop.de had it in pdf-format for 2.50€, in their ebook-of-the-week section. Looks like that was a darn good deal
- Matthias
"C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off." - Bjarne Stroustrup
-
December 31st, 2010, 08:40 AM
#27
Re: Can operator= assign const member?
 Originally Posted by marten_range
The problem I see with this is that the assignment operator breaks the semantics of the const variable.
If you want to support assignment then the member variable shouldn't be const.
I know this is a zombie thread but I find it quite interesting so I reply anyway.
Many felt the strict physical interpretation of C++ constness was too rigid and so the mutable keyword was introduced. It allows for a more logical interpretation of constness and in my view assignment of const objects falls well into this category. I can't see why it should be considered more malign than using the mutable keyword really.
Say you have a small mutable value object like this,
Code:
struct Mutable {
int a;
Mutable() : a(0) {}
explicit Mutable(int a) : a(a) {}
};
If you want to make it immutable a natural approach would be to simply declare 'a' const,
Code:
struct Immutable {
const int a; // variable is declared const
Immutable() : a(0) {}
explicit Immutable(int a) : a(a) {}
};
Now the 'a' variable cannot be changed after object creation which is what you want. What you probably don't want is that the object is forever stuck in the variable where it was created. You cannot do this,
Code:
Immutable m1(43);
Immutable m2(7);
m2 = m1; // not allowed
m1 = m2; // not allowed
The m1 and m2 variables behave like if they were declared const which they aren't so this definately is more constness than you bargained for.
To overcome this you have two options. One is to supply an assignment operator which casts away const, like this,
Code:
struct Immutable1 {
const int a;
Immutable1() : a(0) {}
explicit Immutable1(int a) : a(a) {}
Immutable1 operator=(const Immutable1& rhs) {
*(const_cast<int*>(&a)) = rhs.a; // cast away const
return *this;
}
};
Now objects are immutable so the 'a' variable can never change after creation but objects can still be copied and assigned to other variables.
The other option is to make 'a' private and non-const and access it via a const getter function like,
Code:
struct Immutable2 {
int a() const { // a getter
return a_;
}
Immutable2() : a_(0) {}
explicit Immutable2(int a) : a_(a) {}
private:
int a_; // private non-const
};
Well, before I came upon this thread I probably would've preferred the second approach but I'm not so sure anymore. Okay, the cast in the first approach is ugly but it has the advantage of the 'a' variable actually being declared const and thus safer from any accidental modification.
What do you think? Maybe there's some third option?
Last edited by nuzzle; December 31st, 2010 at 09:05 AM.
-
December 31st, 2010, 10:28 AM
#28
Re: Can operator= assign const member?
 Originally Posted by nuzzle
To overcome this you have two options. One is to supply an assignment operator which casts away const, like this,
As mentioned above, this is undefined behavior according to the standard.
 Originally Posted by nuzzle
Now objects are immutable so the 'a' variable can never change after creation but objects can still be copied and assigned to other variables.
The value of 'a' can change, namely through the assignment operator. Which is exactly what is bad about this IMO. If I see a member variable is const, I expect it won't change, because that is exactly what it means. So IMO declaring a variable as const when it actually can change isn't an advantage, but a bug waiting to happen.
 Originally Posted by nuzzle
What do you think? Maybe there's some third option?
A third option could be to check in run-time whether the value of the const member variables is equal.
Code:
struct Foo
{
int m_a;
const int m_b;
explicit Foo(int b) : m_b(b) {}
Foo& operator =(const Foo& that) {
if (m_b != that.m_b) {
throw std::invalid_argument("Cannot assign incompatible Foo.");
}
m_a = that.m_a;
}
};
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
-
January 1st, 2011, 04:00 AM
#29
Re: Can operator= assign const member?
 Originally Posted by D_Drmmr
As mentioned above, this is undefined behavior according to the standard.
Two posters recommend this solution and one is unsure. Now you indicate you're sure that,
*(const_cast<int*>(&a)) = rhs.a; // cast away const
leads to undefined behavior according to the standard. Could you please point out the section you're referring to. If that's true then this "solution" is out of question of course.
If I see a member variable is const, I expect it won't change, because that is exactly what it means. So IMO declaring a variable as const when it actually can change isn't an advantage, but a bug waiting to happen.
Well, the 'a' variable itself of a created object never changes. Both Immutable1 and Immutable2 are immutable indeed. It's just that the far-reaching restrictions of physical constness are somewhat relaxed (just like they are when mutable is used). You still have logical constness of the 'a' variable. It can never change.
I find it both unexpected and unwanted that just because you declare a variable const then objects cannot be freely assigned anymore. Consider my Immutable2 example. You cannot declare the 'a_' variable const although it's a private constant that should never change after object creation. Because if you do, Immutable2 variables will behave as if they were declared const although they aren't.
So I think physical constness of variables induces an unhealthy coupling between variables and values. One interesting suggesting to resolve this at the language level was presented in this thread,
Code:
struct Suggestion {
mutable const a;
};
It would mean that although 'a' never changes once a Suggestion object is created, it's still possible to copy Suggestion objects between Suggestion variables.
Well, it looks like I'm back to the Immutable2 solution. Especially if Immutable1 gives undefined behavior as you claim.
Last edited by nuzzle; January 1st, 2011 at 04:36 AM.
-
January 1st, 2011, 10:55 AM
#30
Re: Can operator= assign const member?
 Originally Posted by nuzzle
Two posters recommend this solution and one is unsure. Now you indicate you're sure that,
*(const_cast<int*>(&a)) = rhs.a; // cast away const
leads to undefined behavior according to the standard. Could you please point out the section you're referring to. If that's true then this "solution" is out of question of course.
All I happen to have here is the draft n2798, but I guess that'll do. Section 7.1.6.1 states in point 4:
Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.
It is followed by an example:
Code:
const int* ciq = new const int (3); // initialized as required
int* iq = const_cast<int*>(ciq); // cast required
*iq = 4; // undefined: modifies a const object
 Originally Posted by nuzzle
Well, the 'a' variable itself of a created object never changes. Both Immutable1 and Immutable2 are immutable indeed. It's just that the far-reaching restrictions of physical constness are somewhat relaxed (just like they are when mutable is used). You still have logical constness of the 'a' variable. It can never change.
I don't understand what you mean. If we take your example that uses const_cast as a valid program (e.g. by assuming a compiler extension that allows this), then the value of 'a' can change.
Code:
Immutable1 m1(43);
Immutable1 m2(7);
m2 = m1;
Before the assignment the value of m2.a is 7, after the assignment it is 43. That means it changed. That's bad, because 'a' was declared const.
 Originally Posted by nuzzle
I find it both unexpected and unwanted that just because you declare a variable const then objects cannot be freely assigned anymore. Consider my Immutable2 example. You cannot declare the 'a_' variable const although it's a private constant that should never change after object creation. Because if you do, Immutable2 variables will behave as if they were declared const although they aren't.
In this case, in a sense yes, but that is only because there is only one member variable. That's why I gave an example with two member variables.
 Originally Posted by nuzzle
So I think physical constness of variables induces an unhealthy coupling between variables and values. One interesting suggesting to resolve this at the language level was presented in this thread,
Code:
struct Suggestion {
mutable const a;
};
It would mean that although 'a' never changes once a Suggestion object is created, it's still possible to copy Suggestion objects between Suggestion variables.
Besides the contradiction in your last sentense, I don't see what's the point. What's the difference with having a non-const member variable? If the idea is that only the copy assignment operator of Suggestion is allowed to change the value of a, then what's the added value over the Immutable2 example you gave?
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|