Есть ли в этом коде C++ утечка памяти?

struct Foo
{
    Foo(int i)
    {
        ptr = new int(i);
    }
    ~Foo()
    {
        delete ptr;
    }
    int* ptr;
};

int main()
{
    {
        Foo a(8);
        Foo b(7);
        a = b;
    }
    //Do other stuff
}

Если я правильно понимаю, компилятор автоматически создаст функцию-член оператора присваивания для Foo. Однако это просто берет значение ptrв bи помещает его в a. Память, выделенная a, изначально кажется потерянной. Я мог бы сделать вызов a.~Foo();перед выполнением присваивания, но я где-то слышал, что вам редко нужно явно вызывать деструктор. Допустим, вместо этого я пишу оператор присваивания для Foo, который удаляет указатель intлевого операнда перед присвоением r-значения l-значению. Вот так:

Foo& operator=(const Foo& other) 
{
    //To handle self-assignment:
    if (this != &other) {
        delete this->ptr;
        this->ptr = other.ptr;
    }
    return *this;
}

Но если я это сделаю, то когда Foo aи Foo bвыйдут за пределы области видимости, не запустятся оба их деструктора, дважды удалив один и тот же указатель ( так как они оба указывают на одно и то же сейчас)?

Редактировать:

Если я правильно понял Андерса К., это правильный способ сделать это:

Foo& operator=(const Foo& other) 
{
    //To handle self-assignment:
    if (this != &other) {
        delete this->ptr;
        //Clones the int
        this->ptr = new int(*other.ptr);
    }
    return *this;
}

Теперь aклонировал int, что b указал и устанавливает на него собственный указатель. Возможно, в этой ситуации deleteи newне нужны, потому что они просто включают ints, но если член данных не был int* а скорее Бар*или еще что-то, может потребоваться перераспределение.

Редактировать 2: Лучшим решением представляется идиома копирования и замены.

19
задан Community 23 May 2017 в 12:34
поделиться