简体   繁体   English

为什么我的复制构造函数不起作用? (C++)

[英]Why is my copy constructor not working? (C++)

I'm studying C++ and created this simple code to practice copy constructors.我正在研究 C++ 并创建了这个简单的代码来练习复制构造函数。

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;
}

I expected this to print我希望这能打印出来
"default constructor called" “调用默认构造函数”
"copy constructor called" “调用复制构造函数”
"copy constructor called" “调用复制构造函数”
as default constructor is called in "Cube C", and copy constructor is called in "return c" and "Cube c2 = foo()".因为默认构造函数在“Cube C”中调用,而复制构造函数在“return c”和“Cube c2 = foo()”中调用。

However my console only shows "default constructor called"但是我的控制台只显示“调用默认构造函数”

Am I misunderstanding on how copy constructor works?我是否误解了复制构造函数的工作原理?

This won't call your copy constructor, instead what happens is that the created object in foo gets initialized to c2.这不会调用您的复制构造函数,而是将 foo 中创建的 object 初始化为 c2。

Cube c2 = foo();

This will call the = assignment operator:这将调用 = 赋值运算符:

Cube c2; // default constructor
c2 = foo(); // default constructor inside foo() and then assignment operator

This will call the copy constructor:这将调用复制构造函数:

Cube c3; // default constructor
Cube c2(c3); // copy constructor

The copy constructor has the syntax:复制构造函数的语法如下:

Cube(const Cube& obj)

It is a constructor that creates a copy of an object from another object.它是一个构造函数,用于从另一个 object 创建 object 的副本。

However my console only shows "default constructor called"但是我的控制台只显示“调用默认构造函数”

Because of copy elision .因为复制省略

Your expectations are right.你的期望是对的。 There're two copy constructions in concept, the 1st one is for return c;概念上有两种复制结构,第一种用于return c; , copy-initialize the return value from c ; 复制初始化c的返回值; the 2nd one is for Cube c2 = foo();第二个是Cube c2 = foo(); , copy-initialize c2 from the return value of foo() . ,从foo()的返回值 复制初始化c2 They're both omitted because of copy elision then the copy constructor is not called at all.由于复制省略,它们都被省略了,然后根本不调用复制构造函数。

For the 1st one,对于第一个,

In a return statement, when the operand is the name of a non-volatile object with automatic storage duration, which isn't a function parameter or a catch clause parameter, and which is of the same class type (ignoring cv-qualification) as the function return type.在返回语句中,当操作数是具有自动存储期限的非易失性 object 的名称时,它不是 function 参数或 catch 子句参数,并且与 ZA2F2ED4F8EBC2CBB164C21A29-qualification 类型相同function 返回类型。 This variant of copy elision is known as NRVO, "named return value optimization".这种复制省略的变体被称为 NRVO,“命名返回值优化”。

For the 2nd one,对于第二个,

In the initialization of an object, when the initializer expression is a prvalue of the same class type (ignoring cv-qualification) as the variable type:在 object 的初始化中,当初始化表达式是与变量类型相同的 class 类型(忽略 cv 限定)的纯右值时:

 T x = T(T(f())); // only one call to default constructor of T, to initialize x

Note that the 2nd one is mandatory since C++17.请注意,第二个是强制性的,因为 C++17。

BTW: Compiling in pre-C++17 mode (to avoid mandatory copy elision) with -fno-elide-constructors option (to avoid potential copy elision) gives the result you expected.顺便说一句:使用-fno-elide-constructors选项(以避免潜在的复制省略)在 C++17 之前的模式下编译(以避免强制复制省略)会得到您预期的结果。 LIVE with gcc与 gcc 一起直播

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM