简短的回答 - 不要这样做。
细节:
// copy constructor
FeatureValue::FeatureValue(const FeatureValue& other)
{
m_size = other.m_size;
delete[] m_value; // m_value NOT INITIALISED - DON'T DELETE HERE!
m_value = new uint8_t[m_size];
for (int i = 0; i < m_size; i++)
{
m_value[i] = other.m_value[i];
}
}
// assignment operator function
FeatureValue& FeatureValue::operator=(const FeatureValue& other)
{
FeatureValue(other); // error C2082: redefinition of formal parameter
return *this;
}
笔记:
- 当调用复制构造函数时,它会参考被复制的对象来构造新对象,但默认构造函数不会在复制构造函数之前运行。这意味着
m_value
当复制构造函数开始运行时具有不确定的值 - 您可以分配给它,但从中读取是未定义的行为,并且delete[]
对它来说更糟(如果有任何事情可能比 UD 更糟!;-))。因此,只需省略该delete[]
行。
接下来,如果operator=
试图利用复制构造函数的功能,它必须首先释放任何m_value
指向的现有数据,否则它将被泄露。大多数人尝试按以下方式执行此操作(已损坏)-我认为这就是您要尝试的:
FeatureValue& FeatureValue::operator=(const FeatureValue& other)
{
// WARNING - this code's not exception safe...!
~FeatureValue(); // call own destructor
new (this) FeatureValue(other); // reconstruct object
return *this;
}
这样做的问题是,如果 FeatureValue 的创建失败(例如,因为new
无法获得它想要的内存),那么FeatureValue
对象就会处于无效状态(例如,m_value
可能指向空间)。稍后当析构函数运行并执行 adelete[] m_value
时,您有未定义的行为(您的程序可能会崩溃)。
你真的应该更系统地处理这个......要么一步一步写出来,要么实现一个有保证的不抛出swap()
方法(很容易做到......只是std::swap()
m_size
和m_value
,并使用它ala:
FeatureValue& FeatureValue::operator=(FeatureValue other)
{
swap(other);
return *this;
}
这既简单又干净,但它有几个小的性能/效率问题:
最终,可能存在不同的复制构造函数的原因operator=
- 而不是让编译器自动从另一个创建一个 - 是最佳高效的实现不能 - 通常 - 以您希望的方式相互利用。