当复制构造函数在 C++ 中不可用时,为什么不调用复制赋值运算符?
Why isn't the copy assingnment operator called when the copy construcotr is not available in C++?
为什么假设我有一个这样声明的对象:Obj o1;
由默认构造函数初始化(这里不是很重要,o1
是如何初始化的,关键是它被初始化了) 然后我以这种方式创建另一个对象: Obj o2 = o1;
复制构造函数被隐式调用,但是如果我删除复制构造函数,那么,我会得到一个编译错误。为什么对象 o1
不是 assigned/copied 到 o2
,就像这里:Obj o1; Obj o2; o2 = o1;
?为什么编译器会尝试在任何实例中调用构造函数? Obj o2 = o1;
中的 =
运算符是否重载?
如评论中所述,这
Obj o2 = o1;
与赋值无关。使用 =
进行初始化有点不幸,而且常常令人困惑,否则 =
表示赋值。
评论中也提到,operator=
必须假定左侧运算符已经存在。考虑这个有点做作的例子:
#include <vector>
struct my_vect {
my_vect() : data(2) {}
my_vect(const my_vect& other) : data(other.data) {}
my_vect& operator=(my_vect& other) {
// this has already been constructed,
// hence data.size() is 2 already
data[0] = other.data[0];
data[1] = other.data[1];
return *this;
}
private:
std::vector<int> data;
};
它是一个包含 std::vector
的结构,其大小始终为 2
。该向量在构造 my_vect
时被初始化。当将一个 my_vect
分配给另一个时, data
不需要初始化。只有值必须被复制。因为 operator=
假定左侧运算符已经正确构造(它只是复制到 data[0]
和 data[1]
),所以它不可能用于构造对象(在示例中,访问 data[0]
或 data[1]
将超出范围)。
TL;DR: 构造函数构造对象。分配分配给一个已经存在的对象。那是两个根本不同的东西。
为什么假设我有一个这样声明的对象:Obj o1;
由默认构造函数初始化(这里不是很重要,o1
是如何初始化的,关键是它被初始化了) 然后我以这种方式创建另一个对象: Obj o2 = o1;
复制构造函数被隐式调用,但是如果我删除复制构造函数,那么,我会得到一个编译错误。为什么对象 o1
不是 assigned/copied 到 o2
,就像这里:Obj o1; Obj o2; o2 = o1;
?为什么编译器会尝试在任何实例中调用构造函数? Obj o2 = o1;
中的 =
运算符是否重载?
如评论中所述,这
Obj o2 = o1;
与赋值无关。使用 =
进行初始化有点不幸,而且常常令人困惑,否则 =
表示赋值。
评论中也提到,operator=
必须假定左侧运算符已经存在。考虑这个有点做作的例子:
#include <vector>
struct my_vect {
my_vect() : data(2) {}
my_vect(const my_vect& other) : data(other.data) {}
my_vect& operator=(my_vect& other) {
// this has already been constructed,
// hence data.size() is 2 already
data[0] = other.data[0];
data[1] = other.data[1];
return *this;
}
private:
std::vector<int> data;
};
它是一个包含 std::vector
的结构,其大小始终为 2
。该向量在构造 my_vect
时被初始化。当将一个 my_vect
分配给另一个时, data
不需要初始化。只有值必须被复制。因为 operator=
假定左侧运算符已经正确构造(它只是复制到 data[0]
和 data[1]
),所以它不可能用于构造对象(在示例中,访问 data[0]
或 data[1]
将超出范围)。
TL;DR: 构造函数构造对象。分配分配给一个已经存在的对象。那是两个根本不同的东西。