Can operator= assign const member?
Code:
Class A {
public:
A& operator=(const A& rhs);
private:
const int i;
int j;
};
A& A::operator=(const A& rhs) {
j = rhs.j; // this is OK
i = rhs.i; // compiler error! how can I make this work?
}
// Not shown: operator= will check for assignment to self
// and return *this, like all good assignment operators.
Thanks for any help!
Re: Can operator= assign const member?
What's the purpose of assigning const member, in your sense?
You also did not have constructor in class that assigns const data member.
Anyways, you can use C-Style casting or const_casting to do that:
Code:
A& A::operator=(const A& rhs) {
j = rhs.j; // this is OK
*(const_cast<int*>(&i)) = rhs.i; // compiler error! how can I make this work?
}
Re: Can operator= assign const member?
Re: Can operator= assign const member?
I need assignment operator so that I can use in STL containers (std::vector for now). But as I'm typing this, I'm thinking that maybe I should just use containers of pointers (A*). That's probably the more efficient way to go, anyway.
You're right, I didn't show my ctors. Those were easier to write, initializing the const member in the member initialization list.
So, I'll try containers of pointers, and use your const_cast suggestions if I need to.
Thanks
Re: Can operator= assign const member?
If you really need to have const members then pointers are the way to go as one should always strive to avoid casting.
But raw pointers doesn't work to well with the standard containers and algorithms. What you could do is using a reference counted smart pointer such as boost::shared_ptr (http://www.boost.org/libs/smart_ptr/smart_ptr.htm).
Code:
std::vector< boost::shared_ptr<A> > my_vector;
Re: Can operator= assign const member?
This is an interesting question.
Is that really the way to go? Using const_cast<> sounds like the quick and dirty way. It also breaks the class, because you can abuse the operator= to assign to a const member. That doesn't sound like a good idea.
On the other hand, since STL containers are built around object copies, there has to be a cleaner solution, no?
Re: Can operator= assign const member?
Sorry, missed your post. Using pointers sounds like a reasonable solution, though you will run into trouble when using STL algorithms, because they will be invoked on the pointers, not on the pointees. There are several solutions to this of course, but one should keep it in mind.
Re: Can operator= assign const member?
This works in VC7.0:
Code:
#include <utility>
#include <iostream>
using namespace std;
class foo
{
public:
int j;
const int i;
foo() : j(1), i(10) { }
foo(int j_, int i_) : j(j_), i(i_) {}
foo(const foo& f) : j(f.j), i(f.i) {}
foo& operator=(const foo& rhs)
{
foo temp(rhs);
swap(temp);
return *this;
}
private:
void swap(foo& other)
{
std::swap(j, other.j);
std::swap(const_cast<int&>(i), const_cast<int&>(other.i));
}
};
int main()
{
foo f1(3,2);
foo f2;
f2 = f1;
cout << "f2 = (" << f2.j << ", " << f2.i << ")" << endl;
int t;
cin >> t;
}
Now, how about doing it when the class contains a reference variable?
Re: Can operator= assign const member?
Doesn't that cause undefined behavior (using const_cast and then modifing the member)?
Re: Can operator= assign const member?
Not sure that I see the difference between Graham's code and the prior suggestion to const_cast; seems they both have the same result. In fact, it might be considered more inefficient because of constructing the extra object "temp".
As I've thought about this more today, I'm resigning myself to the fact that your only opportunity to have control over const and reference members is during initialization. Once the object is constructed and you can call the assignment operator, it's too late to make any changes. Thus, if you want to identical copies of an object you must use the copy ctor. I think this is the only consistent answer to my question about const ints and Graham's question about references.
Of course no assignment operator precludes putting the objects directly into an STL container, but you can always use containers of pointers (as long as you're careful).
Re: Can operator= assign const member?
I also disregard with the post given by Graham. It does not matter if it works in VC7 and not in VC6, but it complicates the problem. All in all, we need to use 'const_cast' operator, whether we use '=' or 'std::swap'.
And yes, why "swapping" at all?? We need to copy from source to destination, not exchanging them..!
Re: Can operator= assign const member?
Quote:
Originally Posted by Ajay Vijay
And yes, why "swapping" at all?? We need to copy from source to destination, not exchanging them..!
Exception safety. If you changed j, and then the modification of i threw an exception (it will of course not do that in this example, but might if i was an user-defined type), the object would be in an undefined state. (bad) Graham's version doesn't suffer from that problem.
Re: Can operator= assign const member?
I like the idea of exception safety, but sorry, I don't see it in Graham's code. If an exception occurs in foo::swap things could still be left in a bad state.
To implement exception safety, seems there should be a mechanism to catch the exception and undo partial changes.
Re: Can operator= assign const member?
Quote:
Originally Posted by n.marler
I like the idea of exception safety, but sorry, I don't see it in Graham's code. If an exception occurs in foo::swap things could still be left in a bad state.
To implement exception safety, seems there should be a mechanism to catch the exception and undo partial changes.
The entire idea behind the swap() technique is that swap() doesn't throw. However, using const_cast to modify a const value will yield undefined behaviour, I think.
Semantically, I'd say that objects with const members are not assignable and thus cannot be safely put into standard containers.
Re: Can operator= assign const member?
You could use the 'mutable' keyword on your const member. It only works for members though.
Darwen.