Вызывает ли оператор присваивания конструктор копирования? - PullRequest
0 голосов
/ 16 марта 2020
#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 вызывает конструктор копирования и выделяет память для целого числа. Нет проблем с этим, и c.p, и a.p указывают на разные области памяти. Но строка b=a заставляет b.p и a.p указывать на одну и ту же область памяти. Я создал свой собственный конструктор копирования, b.p и a.p должны были указывать на разные области памяти. Что тут происходит?

Редактировать: Точнее, мой вопрос, в чем разница между неявно определенным конструктором копирования и неявно определенным оператором назначения копирования?

Ответы [ 5 ]

3 голосов
/ 16 марта 2020
b=a; 

Здесь также выполняется побитовое копирование (ap и bp, указывающие на одно и то же местоположение), оно не вызывает конструктор копирования, потому что конструктор вызывается, когда b определено (конструктор по умолчанию). Так что вам придется перегружать = operator

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

     return *this;
}

Добавьте это в свой тест класса, и вам нужно проверить, выделяется ли память новым или нет, потому что new может не выделить выделенную память.

Но здесь конструктор копирования называется

test c=a;
1 голос
/ 16 марта 2020

Если вы действительно хотите использовать * 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;
};
0 голосов
/ 16 марта 2020

Не знаю почему, но если я:

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 указывают на разные адреса

0 голосов
/ 16 марта 2020

Попробуйте это:

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;
}
0 голосов
/ 16 марта 2020

Вам нужно определить operator =. Конструктор копирования не будет вызываться для уже созданного объекта.

например,

test&operator=(const test&t)
{
    if(p)delete p;
    p=new int(*t.p);
    return *this;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...