这是一个最小的示例,摘自一个较大的项目。
#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的有效方法吗?
答案 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构造函数相同。