4.复制构造函数
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。