Are const references to members safe

2019-06-21 09:43发布

问题:

If I use a const reference to another member, is it possible that this reference gets invalidated?

class Class {
public:
    const int &x{y};
private:
    int y;
};

For example when I use instances of this class in a vector which increases its capacity after a push_back. According to the standard all iterators and references are invalidated if a vector has to increase its capacity. Is the reference still valid after that?

回答1:

This is currently not safe, as when you copy an instance of Class, x will reference the y of the copied object, not its own y. You can see this by running the following code:

int main()
{
    Class a{};
    std::vector<Class> vec;
    vec.push_back(a);

    //these lines print the same address
    std::cout << &(a.x) << std::endl;
    std::cout << &(vec[0].x) << std::endl;
}

You can fix this by writing your own copy constructor and assignment functions to correctly initialize x:

Class (const Class& rhs) : x{y}, y{rhs.y} {}

This is safe, becausex and y will only be destroyed along with your object. Invalidation of references for std::vector means references to the vector elements:

Class c;
std::vector<Class> vec;
vec.push_back(c);

Class& cr = vec[0];
//other operations on vec
std::cout << c.x; //fine, that reference is internal to the class
std::cout << cr.x; //cr could have been invalidated


回答2:

Assuming this is a reference to another member from the same instance, you need to override copy constructor to initialize it. Default copy constructor will copy the reference to 'y' from the old instance which might be invalidated.

Why do you need a reference to a member is another question.

P.S. also you need to override an assignment operator for the same reason.