开发者

Copying a C++ class with a member variable of reference type

开发者 https://www.devze.com 2023-01-18 21:39 出处:网络
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\" pr

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消