为什么复制构造函数不需要检查输入对象是否指向自身?
Why does copy constructor not need to check whether the input object pointers to itself or not?
正如下面的代码,复制赋值运算符必须检查输入对象是否指向自身。我想知道为什么复制构造函数不需要做同样的检查。
我是C++新手。如果能在这个问题上得到一些帮助,我将不胜感激。
class rule_of_three
{
char* cstring; // raw pointer used as a handle to a dynamically-allocated memory block
void init(const char* s)
{
std::size_t n = std::strlen(s) + 1;
cstring = new char[n];
std::memcpy(cstring, s, n); // populate
}
public:
rule_of_three(const char* s = "") { init(s); }
~rule_of_three()
{
delete[] cstring; // deallocate
}
rule_of_three(const rule_of_three& other) // copy constructor
{
init(other.cstring);
}
rule_of_three& operator=(const rule_of_three& other) // copy assignment
{
if(this != &other) {
delete[] cstring; // deallocate
init(other.cstring);
}
return *this;
}
};
有时会发生自我赋值,这是类正常使用的一部分。
将尚未构造的对象作为参数传递给其自己的复制(或移动(构造函数是不正常的。虽然本身不是未定义的行为1,但没有充分的理由这样做,而且通常不会发生。它可能是偶然发生的,或者如果有人故意试图破坏你的课程。
因此,传统上复制(和移动(构造函数不检查&other != this
。
但是,如果您想要一些额外的安全性,没有什么能阻止您这样做:
rule_of_three(const rule_of_three& other) // copy constructor
{
assert(&other != this);
init(other.cstring);
}
1[basic.life]/7
似乎允许这样做,只要您不访问尚未构造的对象本身。允许使用&
获取其地址。
假设你有像冲锋队这样的简单对象:
class Stormtrooper
{
char* cstring; // raw pointer used as a handle to a dynamically-allocated memory block
void clone(const char* s)
{
std::size_t n = std::strlen(s) + 1;
cstring = new char[n];
std::memcpy(cstring, s, n); // populate
}
public:
Stormtrooper(const char* s = "I am a Stormtrooper clone") { clone(s); }
~Stormtrooper()
{
delete[] cstring; // deallocate
}
Stormtrooper(const Stormtrooper& other) // copy constructor
{
clone(other.cstring);
}
Stormtrooper& operator=(const Stormtrooper& other) // copy assignment
{
if(this != &other) {
delete[] cstring; // deallocate
clone(other.cstring);
}
return *this;
}
};
如果您想将冲锋队分配给另一个冲锋队,检查两个冲锋队是否已经相同(通常是相同的(很有用。通过这种方式,您可以避免 clone(( 操作,因为冲锋队已经相同了。
但是如果你想创建一个新的冲锋队,并且你希望他与另一个冲锋队相同(像往常一样(,你可以复制构造它,在这种情况下,clone(( 操作将正确执行。
通过这种方式,您可以非常轻松地创建整个冲锋队军队。
相关文章:
- 是否需要删除包含对象的"pair"?
- 是否删除在对象构造过程中创建的对象
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 在这种情况下,java对象是否可以调用本机函数
- 返回指向对象的指针的函数调用是否为 prvalue?
- 具有引用成员的结构是否具有唯一的对象表示形式
- 对象初始化中是否允许指向此成员的指针?
- COM :是否可以查看是否存在对我的某个 COM 对象的进程外引用?我可以释放它吗?
- 堆分配的对象是否存在永不为空的唯一所有者?
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- 是否可以使用一个类来控制 C++ 中另一个类的对象?(阿杜伊诺)
- 在对象指针上调用 Delete 是否会递归删除其动态分配的成员
- QFileSystemModel 对象是否会被删除?
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 是否可以使用分配器对象来释放另一个分配器分配的内存?
- 线程调用的函数对对象删除是否安全?
- 将对象的字节复制到数组并再次复制回来是否安全
- std::memmove在同一对象之间是否始终安全
- 类对象在 c++ 中是否具有数据类型?
- 是否可以将不可复制的成员用作使对象不可复制的替代方法?