0%

C++之拷贝构造函数

拷贝构造函数是一种特殊的构造函数, 其形参必须是本来对象的一个引用,但并不限制为const,一般普遍的会加上const限制. 使用拷贝构造函数的目的是一个已经存在的对象来初始化同类的一个新对象.

声明拷贝构造函数的语法规则如下:

类名(类名 &对象名)

通常构造函数只在对象创建时被调用, 而拷贝构造函数在以下情况下会被调用:

  • 当使用类的一个对象去初始化该类的一个新对象时.
  • 如果一个函数的形参是类的对象, 那么当调用该函数时对应类的拷贝构造函数也会被调用.
  • 如果函数的返回值是类的对象, 那么该函数返回时对应类的拷贝构造函数也会被调用.(但一般编译器会进行返回值优化, 减少临时对象带来的开销,参考 C++返回值为对象时复制构造函数不执行怎么破)

示例代码如下:

#include <iostream>
using namespace std;

class Time
{
    int hour, minute, second;
public:
    Time():hour(0),minute(0),second(0){};
    Time(Time const &t);
    ~Time();
    void getTime();
    void setTime(int h, int m, int s);
};

Time::Time(Time const &t)
{
    hour = t.hour;
    minute = t.minute;
    second = t.second;
    cout << "拷贝构造函数被调用!!!" << endl;
}


void Time::getTime()
{
    cout << "Time is " << hour << ":" << minute << ":" << second << endl;
}

void Time::setTime(int h, int m, int s)
{
    if (m < 0 || m > 59 || s < 0 || s > 59 || h < 0 || h > 23) {
        cout << "set time error" << endl;
        return;
    }
    hour = h;
    minute = m;
    second = s;
}

Time::~Time(){
    cout << "销毁" << endl;
}

void fun0(Time t){}
Time fun1(){
    Time t;
    return t;
}

int main(int argc, const char * argv[]) {
    Time t0;
    t0.setTime(12, 12, 12);
    Time t1 = t0;
    t1.getTime();
    fun0(t0);
    Time t2 = fun1();
    t2.getTime();
    return 0;
}

当没有自定义拷贝构造函数时,C++会提供一个默认的拷贝构造函数,但是如果类的数据成员中包含指针类型或者静态成员变量时, 不推荐使用默认的拷贝构造函数. 因为默认的拷贝构造函数只能实现浅拷贝, 会带来数据安全方面的隐患.

一个类中可以存在多个拷贝构造函数, 但是,一旦一个类中只存在一个参数为 X& 的拷贝构造函数, 那么就不能使用const X 或 volatile X 的对象进行拷贝初始化 (即不能使用Time t2 = fun1()的方式).

对于一个类X, 如果它的一个构造函数的第一个参数是这四者(X&, const X&, volatile X&或 const volatile X&)之一, 且没有其他参数或其他参数都有默认值, 那么这个就是拷贝构造函数.