复制构造函数必须将形参指定为 const 引用
若复制构造函数写成如下:
CBox(CBox initB);
由于是按值传递,所以编译器会首先创建对象的副本,而创建对象的副本需要调用复制构造函数,又会创建新的对象,新对象又会调用复制构造函数
会持续不休,最终得到对复制构造函数的无穷调用。
解决方法如下:
CBox(const CBox & initB);
由于是引用形参,因此没有复制发生,const 限定符用来确保该函数不能修改实参。
class CMessage { private: char * m_pMessage; public: void showIt()const { cout << m_pMessage << endl; } //构造函数 CMessage(const char* text="Default message") { size_t length{strlen(text)+1}; m_pMessage = new char[length+1]; strcpy_s(m_pMessage,length+1,text); } //析构函数 ~CMessage() { cout << "Destructor called" << endl; delete[]m_pMessage; } }; void displayMessage(CMessage localMsg) { cout <<"the message is:" << endl; localMsg.showIt(); } int main() { CMessage thought{"Amiss is as good as a mile"}; displayMessage(thought); thought.showIt(); return 0; }
运行上面程序我们会发现出现异常,原因是因为在 displayMessage(CMessage localMsg) 函数调用中按值传递创建了实参的副本,
而由于使用默认复制构造函数,对象和对象的副本的数据成员 m_pMessage,共同指向同一块内存区域。
displayMessage(CMessage localMsg)函数中的对象副本在离开函数后便调用析构函数用 delete[]m_pMessage 释放了内存。
所以 thought 对象的数据成员也被释放了。
下面代码依旧同样的问题:
class CMessage { private: char * m_pMessage; public: void showIt()const { cout << m_pMessage << endl; } CMessage(const char* text="Default message") { size_t length{strlen(text)+1}; m_pMessage = new char[length+1]; strcpy_s(m_pMessage,length+1,text); } ~CMessage() { cout << "Destructor called" << endl; delete[]m_pMessage; } }; int main() { CMessage motto1{"Amiss is as good as a mile"}; CMessage motto2{motto1}; return 0; }
解决办法:建立自己的复制构造函数
CMessage(const CMessage & aMess) { size_t len{strlen(aMess.m_pMessage)+1}; this->m_pMessage = new char[len]; strcpy_s(m_pMessage,len,aMess.m_pMessage); }