对象 && 复制构造函数

复制构造函数必须将形参指定为 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);
}

 

posted @ 2016-10-06 20:41  韵切  阅读(323)  评论(0编辑  收藏  举报