如何(或为什么)调用复制构造函数?

KcF*_*nMi 1 c++ constructor

#include <iostream>

using namespace std;

struct Car
{
    int size = 4;
    int* tires = nullptr;

    Car()
    {
        cout << "ctor" << endl;
        tires = new int[size];
    }

    Car(const Car& car)
    {
        cout << "copy ctor" << endl;
        tires = new int[size];
        memcpy(tires, car.tires, size*sizeof(int));
    }

    Car& operator= (Car& car)
    {
        cout << "copy assignment operator" << endl;
        tires = new int[size];
        memcpy(tires, car.tires, size*sizeof(int));
        return *this;
    }

     ~Car()
    {
        cout << "dtor" << endl;
        delete tires;
    }
};

int main()
{
    cout  << "starting..." << endl;

    Car car1;
    car1.tires[0] = 2;

//    Car car2(car1); // #1
    Car car2 = car1; // #2 I was expecting the assingment operator to be called here

    cout << car1.tires[0] << " " << car2.tires[0] << endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我明白为什么复制构造函数在 #1 处被调用,但是它最终是如何在 #2 处被调用的呢?

Rem*_*eau 5

该声明:

Car car2 = car1;

不是作业,就像你想的那样。赋值只能发生在现有对象上,而不能在创建对象时发生。

上面的语句实际上是初始化,特别是Copy Initialization

句法

T object = other; (1)

...

复制初始化的效果是:

  • ...

  • 否则,如果是 类类型,且isT类型的 cv 未限定版本或派生自的类,则检查 的非显式构造函数,并通过重载决策选择最佳匹配。然后调用该构造函数来初始化该对象。otherTTT

  • ...

因此,在您的情况下,编译器会发现复制构造函数是匹配的,并将该语句视为已编写的语句Car car2(car1);

这就是调用复制构造函数的原因。