Copying a C++ class with a member variable of reference type
I've a class which stores a reference to its parent, the reference is passed in the constructor. If I try to copy an instance I get an error "error C2582: 'operator =' function is unavailable" presumably down to the reference being non-assignable.
Is there a way around this, or do I just change the variable to pointer instead of reference?
e.g (over-simplified but I think has the key points):
class M开发者_如何学JAVAyClass
{
public:
MyClass(OtherClass &parent) : parent(parent) {}
private:
OtherClass &parent;
};
MyClass obj(*this);
.
.
.
obj = MyClass(*this);
There is a way to do it and still use a reference, use a reference_wrapper
. So
T& member;
becomes
std::reference_wrapper<T> member;
Reference wrappers are basically just re-assignable references.
I don't recommend this at all
but if you are really gung ho about doing this:
#include <new>
MyClass::MyClass(const MyClass &rhs): parent(rhs.parent)
{
}
MyClass &MyClass::operator=(const MyClass &rhs)
{
if (this!=&rhs)
{
this->~MyClass();
new (this) MyClass(rhs);
}
return *this;
}
Yes, if you need to support assignment, making it a pointer instead of a reference is nearly your only choice.
Yes just make the member a pointer. A reference won't be able to be reseated, and there is no work-around.
Edit: @"Steve Jessop" makes a valid point to how work-around the problem using the PIMPL idiom (private implementation using a "d-pointer"). In an assignment, you will delete the old implementation and create a new one copy-constructed from the source object's d-pointer.
You need to implement a copy constructor and initialize the reference in that copy constructor, to point to the same reference as the original object.
I would make it a boost::shared_ptr. You can be pretty rough with these and they take care of themselves. Whereas using a raw pointer means tha you have to worry about that object being kept alive
As mentioned by others, using std::reference_wrapper can be used. The helper functions std::ref() and std::cref() can be used, too. Unlike other postings, C++03 introduced reference_wrapper, ref() and cref() in the namespace std::tr1, so you have options if you're not using C++11 or beyond.
精彩评论