拷贝构造函数的英文:Copy Constructor

拷贝构造函数是构造函数的一种。

当利用已存在的对象创建一个新对象时(类似于拷贝),就会调用新对象的拷贝构造函数进行初始化。

拷贝构造函数的格式是固定的,接收一个const引用作为参数。

class Car
{
private:
    int price;
    int length;
public:
    Car(int price = 0, int length = 0) : price(price), length(length) {  }

    // 拷贝构造函数
    Car(const Car &car) : price(car.price), length(car.length)
    {
        printf("Car(Car &car)\n");
    }

    void display()
    {
        printf("price = %d, length = %d\n", this->price, this->length);
    }
};

int main()
{
    Car c(1, 2);
    // 利用已经存在的c对象创建了一个c1新对象
    // c1初始化时会调用拷贝构造函数
    Car c1(c); // 等价于 Car c1 = c;
    c1.display();
    
    Car c2;
    // 这里不会调用拷贝函数,这里仅仅只是赋值操作,给c1里的值赋值给c2
    c2 = c1;

    return 0;
}

调用父类的拷贝构造函数

class Person
{
private:
    int age;

public:
    Person(int age = 0) : age(age) {  }

    Person(const Person &p) : age(p.age) {  }

    int get_age() { return this->age; }
};

class Student : Person
{
private:
    int score;

public:
    Student(int age = 0, int score = 0) : Person(age), score(score) {  }

    //                          调用父类的拷贝函数
    Student(const Student &s) : Person(s), score(s.score) {  }

    void display()
    {
        printf("age = %d, score = %d.\n", this->get_age(), this->score);
    }
};

浅拷贝、深拷贝

编译器默认的提供的拷贝是浅拷贝(shallow copy)。

浅拷贝

将一个对象中所有成员变量的值拷贝到另一个对象。

如果某个成员变量是个指针,只会拷贝指针中存储的地址值,并不会拷贝指针指向的内存里的内容,这样的话,可能会导致堆空间多次free的问题。

深拷贝

如果需要实现深拷贝(deep copy),就需要自定义拷贝构造函数。

将指针类型的成员变量所指向的内存空间,拷贝到新的内存空间。