当复制结构在 C++ 中不可用时,为什么不调用复制评估运算符?

Why isn't the copy assingnment operator called when the copy construcotr is not available in C++?

提问人:pauk 提问时间:11/8/2021 更新时间:11/8/2021 访问量:96

问:

为什么假设我有一个这样声明的对象:它是由默认构造函数初始化的(这里不是很重要,如何初始化,重点是它被初始化了)并且我以这种方式创建另一个对象:复制构造函数被隐式调用,但是如果我删除复制构造函数,那么,我会得到编译错误。为什么对象没有被赋值/复制到 ,如下所示: ?为什么编译器在任何情况下都尝试调用构造函数?操作员是否超载?Obj o1;o1Obj o2 = o1;o1o2Obj o1; Obj o2; o2 = o1;=Obj o2 = o1;

C++ 构造函数 constructor-重载 复制赋值

评论

2赞 alex_noname 11/8/2021
命名变量的复制初始化中的等号 = 与赋值运算符无关。赋值运算符重载对复制初始化没有影响。 cp偏好
1赞 Quimby 11/8/2021
赋值运算符假定左侧已存在。
0赞 Some programmer dude 11/8/2021
复制初始化可能会省略调用复制构造函数,但复制构造函数必须仍然可用(即未删除)才能复制对象。
0赞 molbdnilo 11/8/2021
C++ 中的许多符号在不同的上下文中表示不同的事物。 就是其中之一。=

答:

3赞 463035818_is_not_an_ai 11/8/2021 #1

正如评论中提到的,这

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::vector2my_vectmy_vectdataoperator=data[0]data[1]data[0]data[1]

TL的;DR:构造函数构造对象。赋值指定给已存在的对象。这是两件根本不同的事情。

评论

0赞 pauk 11/8/2021
是的,但这里我有 ,并且足以初始化对象,只要调用默认构造函数,因此只要没有提供复制构造函数,我就应该执行。Obj o1 = o2;Obj o1;Obj o1 = o2;Obj o1; o1 = o2;
0赞 pauk 11/8/2021
但为此,必须分别执行两条指令。
0赞 463035818_is_not_an_ai 11/8/2021
@pauk这可能会发生,但这不是C++的工作方式。一般来说,默认构造加上后续赋值比仅复制构造更昂贵,因此在 C++ 中,您必须在需要时明确请求它是很好的。我的意思是,没有什么能阻止你写作,因为这是你想要的Obj o1; o1 = o2;