首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么我的拷贝构造函数不工作?(C++)

为什么我的拷贝构造函数不工作?(C++)
EN

Stack Overflow用户
提问于 2020-06-02 14:31:58
回答 2查看 127关注 0票数 2

我正在研究C++,并创建了这个简单的代码来练习复制构造函数。

代码语言:javascript
运行
复制
class Cube{
    private:
        double length;
    public:
        Cube(){
            length = 1;
            cout << "default constructor called" << endl;
        };
        Cube(const Cube& obj){
            length = obj.length;
            cout << "copy constructor called" << endl;
        };
};

Cube foo(){
    Cube c;
    return c;
}

int main(){
    Cube c2 = foo();
    return 0;
}

我希望这能打印出来

“默认构造函数名为”

“复制构造函数已调用”

“复制构造函数已调用”

因为在“立方体C”中调用默认构造函数,而在“返回c”和“立方体c2 = foo()”中调用复制构造函数。

然而,我的控制台只显示“默认构造函数名为”

我是不是误解了拷贝构造函数的工作方式?

EN

回答 2

Stack Overflow用户

发布于 2020-06-02 14:36:01

这不会调用您的复制构造函数,而是foo中创建的对象被初始化为c2。

代码语言:javascript
运行
复制
Cube c2 = foo();

这将调用=赋值运算符:

代码语言:javascript
运行
复制
Cube c2; // default constructor
c2 = foo(); // default constructor inside foo() and then assignment operator

这将调用复制构造函数:

代码语言:javascript
运行
复制
Cube c3; // default constructor
Cube c2(c3); // copy constructor

复制构造函数的语法为:

代码语言:javascript
运行
复制
Cube(const Cube& obj)

它是一个从另一个对象创建一个对象副本的构造函数。

票数 7
EN

Stack Overflow用户

发布于 2020-06-02 15:25:46

但是我的控制台只显示"default constructor called“

因为copy elision

你的期望是对的。在概念上有两个拷贝结构,第一个是return c;copy-initialize来自c的返回值;第二个是Cube c2 = foo();copy-initialize c2来自foo()的返回值。由于copy elision的原因,它们都被省略了,那么复制构造函数根本就不会被调用。

对于第一个,

当操作数是具有自动存储持续时间的非易失性对象的名称,不是函数参数或catch子句参数,并且与函数返回类型相同的类类型(忽略cv-

)时,返回语句中的限定。这种副本省略的变体被称为NRVO,即“命名返回值优化”。

对于第二个,

当初始化器表达式是与变量类型相同类类型(忽略cv-

)的pr值时,对象初始化中的限定:

T x=T(T(f();//只调用一次T的默认构造函数,初始化x

请注意,第二个是强制的,因为C++17。

顺便说一句:在C++17之前的模式下编译(避免强制的复制遗漏)和-fno-elide-constructors选项(避免潜在的复制遗漏)会得到您所期望的结果。LIVE with gcc

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62146129

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档