一个更容易的拷贝分配操作符实现
an easier copy-assignment operator implement?
在C++Primer 5th,13.2.1 class That Acting Like Values中,作者创建了一个类似于值的类,这意味着每个对象都有自己的类管理的资源副本。这个类在下面,它是一个非常简单的类,只包含一个指向字符串的指针,和一个int,member函数只是默认的构造函数和复制控制成员。
class HasPtr{
public:
HasPtr(const std::string &s = std::string()) :ps(new std::string(s)), i(0){}
HasPtr(const HasPtr &p) :ps(new std::string(*p.ps)), i(p.i){}
HasPtr &operator=(const HasPtr &rhs);
~HasPtr(){ delete ps; }
private:
std::string *ps;
int i;
};
下面是操作员的工具=由书籍给出
HasPtr &HasPtr::operator=(const HasPtr &rhs){
auto newp = new std::string(*rhs.ps);
delete ps;
ps = newp;
i = *rhs.i;
return *this;
}
这很好,但我认为我们可以使用下面的实现,它可以避免删除指针并分配新的内存。
HasPtr &HasPtr::operator=(const HasPtr &rhs){
*ps = *rhs.ps;
i = rhs.i;
return *this;
}
我测试我的代码是否有效,甚至是自我分配。但是,这个代码有问题吗?
不,您的代码没有问题。
*ps
本身是一个值类型,因此可以直接赋值。如果您正在进行更改以改进代码,您可能需要更进一步,将ps更改为std::string,而不是std::string*。然后,您可以从HasPtr类中消除对new和delete的需要。
如果
*ps
如果是HasPtr类管理的内存的原始指针,则必须编写代码,例如书中的示例。
在您的原始示例中,您已经将*ps的内容复制到了自己,这是可以的。然而,正如您的注释所建议的,情况可能并不总是如此。
至于其他解决方案,这里有一个(也许类似的事情会在你的书后面解释):
#include <algorithm>
//...
HasPtr &HasPtr::operator=(const HasPtr &rhs)
{
HasPtr temp(rhs);
std::swap(ps, temp.ps);
std::swap(i, temp.i);
return *this;
}
这就是copy/swap
习语。从rhs
创建一个临时,临时的内部与this
的成员交换。最后,临时死亡,带走了this
以前的价值观。
请注意,没有显式的内存分配,因为您最初依赖于复制构造函数来创建临时副本。这意味着该技术需要一个可工作的复制构造函数和一个可运行的析构函数。一旦你有了这些,如果这样做,赋值操作符就非常简单了,因为没有真正的"繁重的工作"编码要做——复制构造函数会处理它
那么这比书中的版本容易吗?这取决于你如何看待它——复制/交换几乎可以在任何情况下使用,在这种情况下,你基本上只需要从"3的规则"中描述的三个函数中的两个的工作实现开始,即复制构造函数和析构函数。分配操作员只是利用其他两个功能,再加上执行简单的交换。
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- GlobalAlloc而不是其他分配方法
- 自定义先决条件对移动分配运算符有效吗
- 我可以重新分配/覆盖std::字符串吗
- 为什么移动语义与动态 mem 分配中的浅拷贝具有相同的行为
- 我可以在C++中从const char*数组中进行std::字符串的零拷贝分配吗
- 一个更容易的拷贝分配操作符实现
- 静态内存分配中的浅拷贝构造函数问题