具有引用成员的类的默认move构造函数

时间:2019-06-18 22:37:08

标签: c++

这是一个最小的示例,摘自一个较大的项目。

#include <vector>
#include <cassert> 
using namespace std; 


class Data
{
    int value_; 
public:
    int const& value = value_;

    Data(int init)
    {
        value_ = init; 
        assert(value == value_);
    }

    //Data(Data const& other) 
    //{
    //  value_ = other.value_;
    //}
    // Data(Data && other) = default; 

    ~Data()
    {
        assert(value == value_); 
    }
};

int main()
{
    std::vector<Data> datas; 
    for (int i = 0; i < 10; ++i)
    {
        datas.push_back(Data(i));
    }
}

在析构函数中的断言有时会失败;在这一点上我不能说。我傻眼了。提供复制c-tor是可行的,但是随后启用默认move-ctor再次失败。

默认移动/复制c-tor如何处理此类引用?我无法使用调试器分析幕后发生的事情。
在C ++中使用public const&是提供getter的有效方法吗?

2 个答案:

答案 0 :(得分:3)

  

默认移动/复制c-tor如何处理此类引用?

副本成员将引用源成员所引用的同一对象。

在这种情况下,引用的对象是另一个成员。因此,如果您从B复制A,则B的引用成员将引用A的对象成员,因为这就是{{ 1}}。如果A被销毁,则A的引用成员将处于悬空状态,并通过具有不确定行为的对象访问该对象(不再存在)。

实际上,您可以使用自定义的copy / move构造函数来初始化对其他对象的引用,但对成员的引用通常是毫无用处的。

  

在C ++中使用public const&是提供吸气剂的有效方法吗?

这不是一个好的解决方案。

答案 1 :(得分:2)

默认的复制构造器

Data(Data const&) = default;

主要等同于:

Data(Data const& rhs) :
    value_(rhs.value_), // Copy value
    value(rhs.value)    // alias the same value as rhs.value, so probably rhs.value_ 
{
}

因此,您不会像预期的那样指向内部成员。

与带有一些std::move的默认move构造函数相同。

相关问题