复制构造函数

1.复制构造函数原型

const class_name(const class_name&)

2.何时会调用

2.1.函数按值传递对象时,会复制对象,调用复制构造函数

2.2.函数返回对象时,会先把这个对象复制一份,调用复制构造函数。

2.3.显示调用复制构造函数

3.默认复制构造函数,会一一复制非静态数据成员。

4.何时需要重写复制构造函数
当牵涉到new动态分配内存的时候,需要考虑是否需要重写。今天实现string类时就遇到了此类问题。

 
string::string(const char* temp){
    //分配的空间比字符串长度大一,多余的空间来存储\0
    length = std::strlen(temp);
    str = new char[length+1];
    std::strcpy(str,temp);
}


string::string(const string & st){
    //复制字符串对象st
    length = st.length;
    str = new char[length + 1];
    std::strcpy(str,st.str);
}

string::~string(){
    delete[] str;
}

如果不重写复制构造函数,即这样:

string::string(const string & st){
    str = st.st;
    length = st.length;
}

两个对象的指针都指向同一块内存,当调用析构函数时,会释放同一块内存两次,这将引发程序崩溃。

5.一同需要考虑的是,默认的赋值运算符=,即:operator=()
默认的赋值运算符也是一一复制静态数据成员。所以呢,有new的地方也应该考虑重写。具体如下:

string& string:: operator = (string& st){
    //st赋值给当前对象
    //对象赋值给自己
    if(&st == this)return *this;
    //释放当前对象的内存
    delete[] str;
    length = st.length;
    str = new char[length + 1];
    std::strcpy(str,st.str);
    return *this;
}

注意:当自身类的引用作为类成员函数参数
时,这个引用的类可以直接访问数据成员。
比如说

string& string:: operator = (string& st){

}

st可以直接访问私有数据成员str。

猜你喜欢

转载自www.cnblogs.com/jielearscoding/p/12509758.html