【转帖】拷贝构造函数与赋值构造函数(operator=)的区别

    技术2025-10-09  11

    转载地址: http://hi.baidu.com/langyy1288/blog/item/c69c71d8cf93432a11df9bf1.html

    对于拷贝构造函数以及赋值构造函数的定义,我就不再啰嗦了,还是给出一个简单的例子,更直观些吧。

    class CStr{

    public:

    CStr(); //默认构造函数

    CStr(const char* psz); //一种广义拷贝构造函数,不过也有人不认同我的看法

    CStr(const CStr& str); //拷贝构造函数

    const CStr& operator=(const CStr& str); //赋值构造函数

    size_t GetSize() const; //这里的const是什么意思?它必须吗?

    operator const char*() const { return m_pdata; }

    protected:    const CStr* _Copy(const CStr& str);

    private:        char* m_pdata;        size_t m_size;    };

    CStr::CStr(){    m_pdata = NULL;    m_size = 0;}

    size_t CStr::GetSize() const{    return m_size;}

    const CStr* CStr::_Copy(const CStr& str){

    if(this != &str)

    {

    if(m_pdata){

    delete[] m_pdata;

    }

    m_size = str.GetSize();

    m_pdata = new char[m_size + 1]; assert(m_pdata);

    strcpy(m_pdata, str);        }

    return this;}

    CStr::CStr(const char* psz) : m_pdata(NULL), m_size(0)

    {

        assert(psz);

    if(m_pdata != psz)

    {

        if(m_pdata){

            delete[] m_pdata;            }

    m_size = strlen(psz);

    m_pdata = new char[m_size + 1]; assert(m_pdata);

    strcpy(m_pdata, psz);

    }}

    CStr::CStr(const CStr& str): m_pdata(NULL), m_size(0){    _Copy(str);}

    const CStr& CStr::operator=(const CStr& str){    return *(_Copy(str));}

    int main(){    const char* psz = "test";    const char* psz1 = "me";    CStr str(psz); //拷贝构造函数,此处调用的是CStr(const char* psz)。     #1    CStr str2(str); // 拷贝构造函数,此处调用的是 CStr(const CStr& str)   #2    CStr str1 = psz1; // 拷贝构造,str1此前并不存在,现在要先构造它。    #3    str = str1; // 真正的赋值构造函数    #4    return 0;}

    上面这个小型的例子,是我刚刚为大家编写的,这个例子主要就是为了阐述赋值构造函数与拷贝构造函数之间的区别,其实,我的看法是,赋值构造函数不应该被称为一个构造函数,充其量只能算得上一个重载的操作符函数。

    在C语言中,我们知道"=="是判等操作符,而"="却是一个赋值操作符,所以只要没有出现"="操作符,也就不会有赋值操作可言。

    我之所以认为赋值构造函数不应该被称为一个构造函数,是因为在调用赋值构造函数的时候,类对象已经存在,自然谈不上构造类对象,它只是对该已经存在的类对象的成员变量进行修改(所谓的赋值)操作。而拷贝构造函数是利用一个已经存在的类对象构造出一个新的类对象。

    回到上面的例子,相信大多数人都应该能分清#1、#2、#4所调用的函数,而对于#3,我想着重说明的是:赋值构造的实际用意是修改一个已有的对象,而现在str1还没有被定义,所以此处还是必须要调用拷贝构造函数先产生一个CStr对象。

    最后,请大家记住:定义与赋值同时进行的话,必须要先定义,所以必须得先调用拷贝构造函数,而对于符合单纯的赋值操作语法的语句(也就是只有两个操作数的表达式)来说,才是真正的调用赋值构造函数。如果大家有什么问题,可以问我,我会尽力为大家讲解。

    最新回复(0)