繁体   English   中英

赋值运算符是否调用复制构造函数?

[英]Does the assignment operator call copy constructor?

#include<iostream>
using namespace std;
class test
{
    int *p;
public:
    test(){p=new int(0);}
    test(const test &src)
    {
        p=new int(*src.p);
    }
    ~test(){delete p;}
    void show(){cout<<*p<<" at "<<p<<endl;}
    void setx(int a)
    {
        *p=a;
    }
};
int main()
{
    test a,b;
    a.setx(10);
    a.show();
    b=a;
    b.show();
    test c=a;
    c.show();
}

在 main() 中, test c=a调用复制构造函数并为整数分配内存。 没问题, cpap指向不同的内存位置。 但是行b=a导致bpap指向相同的内存位置。 我已经创建了自己的复制构造函数, bpap应该指向不同的内存位置。 这里发生了什么?

编辑:准确地说,我的问题是隐式定义的复制构造函数和隐式定义的复制赋值运算符之间有什么区别?

b=a; 

这里也逐位复制完成(ap 和 bp 指向同一位置),它不会调用复制构造函数,因为在定义 b 时调用构造函数(默认构造函数)。所以你必须重载=运算符

test &operator =(const test &src)
{
    *this->p=*src.p;    //copy value not address 

     return *this;
}

将此添加到您的类测试中,您需要检查内存是否由 new 分配,因为 new 可能无法分配请求的内存。

但是这里调用了复制构造函数

test c=a;

如果你真的想使用 *int,我会使用智能指针来简化资源所有权:

class Test
{
public:
    Test(){p=std::shared_ptr<int>(new int(0));}
    Test(const Test &src){p=std::shared_ptr<int>(new int(*(src.p.get())));}
    ~Test()=default;
    Test& operator= (const Test& src) {p = std::make_shared<int>(*(src.p.get())); return *this;}
    void show(){cout<<*(p.get())<<endl;}
    void setx(int a) {*(p.get())=a;}
private:
    std::shared_ptr<int> p;
};

但是,考虑到 int 的生命周期与对象本身相同(因此您不必动态分配它),使用指针或智能指针(混淆代码)并没有太大意义:

class Test
{
public:
    Test():p(0){}
    Test(const Test &src):p(src.p){}
    ~Test()=default;
    Test& operator= (const Test& src) {p = src.p; return *this;}
    void show(){cout<<p<<endl;}
    void setx(int a) {p=a;}
private:
    int p;
};

您需要定义 operator=。 不会为已经构造的对象调用复制构造函数。

例如,

test&operator=(const test&t)
{
    if(p)delete p;
    p=new int(*t.p);
    return *this;
}

尝试这个:

test& operator= (const test& anotherTest)
{
    if (this != &anotherTest) 
    { 
        if ( NULL != this->p )
            *(this->p) = *(anotherTest.p);
        else
            this->p = new int (*anotherTest.p)
    }   

    return *this;
}

我不知道为什么,但如果我:

test a;
a.setx(10);
a.show();
test b = a;
b.show();
test c = a;
c.show();

代替 :

test a,b;
a.setx(10);
a.show();
b=a;
b.show();
test c=a;
c.show();

ap 和 bp 指向不同的地址

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM