C++ 中的复制构造函数和赋值运算符 [已关闭]

copy constructor and assignment operator in C++ [closed]

提问人:Mohamed Salah 提问时间:6/27/2021 更新时间:6/27/2021 访问量:375

问:


想改进这个问题吗?通过编辑这篇文章来更新问题,使其仅关注一个问题。

2年前关闭。

class MyClass
{
private:
    int x;
public:
    MyClass(int x)
    {
        this->x = x;
    }
    MyClass(const MyClass& other)
    {
        this->x = other.x;
    }
};

int main()
{

    MyClass first(1);
    MyClass second = first;        //(1)
    first = second;               // (2)
    MyClass third = MyClass(2);  //  (3)     
}

为什么第一行调用复制构造函数,第二行调用赋值运算符,以及为什么第三行通过调用复制构造函数而不像第一行那样起作用。 当然,第 3 行到底是做什么的.MyClass second = firstfirst = second; MyClass third = MyClass(2);MyClass third = MyClass(2);

C++ OOP 复制构造函数

评论

1赞 Human-Compiler 6/27/2021
这回答了你的问题吗?赋值运算符和复制构造函数有什么区别?
2赞 Sam Varshavchik 6/27/2021
当一个对象已经构造时,它不能再次构造。C++ 不以这种方式工作。因此,必须调用其赋值运算符。就第 3 行的作用而言,它被称为“复制省略”。但是,您的问题需要重新构建,请每个 Stackoverflow 问题只有一个问题。请编辑您的问题,使其仅关注复制构造函数与赋值问题,或复制省略。在将您的第一个问题发布到 Stackoverflow 之前,您应该先参观一下,阅读帮助中心并在此处学习如何提问。
0赞 Scheff's Cat 6/27/2021
一般有不同的含义:(1)是带有初始化的声明。这里是声明和初始值设定项之间的“分隔符”。(2)是一个表达式。这里是赋值运算符。可能会令人困惑的是,同一符号具有不同的含义,具体取决于它出现在哪个上下文中。但是,您可能已经注意到这不是唯一的此类符号。例如,根据它们出现的位置,和 也具有非常不同的含义......====*&
0赞 Dominique 7/22/2021
这个问题是关于一段代码,其中类似的事情(分配对象和启动构造函数)一个接一个地完成,作者似乎不明白两者之间的区别。这是一个很好的问题,甚至是一个有价值的问题,我不同意这个问题是一些“你没有注意”的测试。

答:

1赞 aschepler 6/27/2021 #1

构造函数(包括复制构造函数)用于初始化类对象。赋值运算符用于修改已初始化的对象。

第 (1) 行调用复制构造函数,因为它正在初始化对象。赋值运算符与符号也在此语法中使用这一事实无关。行 (2) 赋值已存在,因此使用赋值运算符。second=first

在 C++14 及更早版本的第 (3) 行中,允许编译器为表达式创建临时对象,然后使用复制构造函数初始化,然后销毁临时对象。但是编译器也可以“省略”(删除)临时对象、复制构造函数和临时析构函数,只需以与原始临时对象相同的方式直接初始化即可。这种复制省略是 C++ 允许优化的一种情况,这可能会导致可观察行为的差异,因为复制构造函数和/或析构函数可能具有优化跳过的副作用(如打印痕迹)。MyClass(2)thirdthird

在 C++17 及更高版本的第 (3) 行中,我们说表达式具有结果对象。因此,表达式指定使用参数直接初始化。不涉及复制构造函数或临时对象。C++17 的这一特性通常被称为“强制复制省略”,因为其行为与编译器能够应用复制省略优化的 C++14 程序相同。但从技术上讲,这不是复制省略,因为不涉及要省略的副本。还有一些其他情况,对于编译器来说,复制省略是可选的。MyClass(2)thirdthird2