Уничтожить объект при разыменовании - PullRequest
0 голосов
/ 10 мая 2018

У меня есть этот код ...

#include <stdio.h>
#include <stdlib.h>

class Foo{
public:
    int *a;
    Foo(int n);
    ~Foo();
    Foo* add(int n);
    void print();
};

Foo::Foo(int n){
    a=(int*)malloc(sizeof(int));
    *a=n;
}

Foo::~Foo(){
    printf("destructor called\n");
    free(a);
}

Foo* Foo::add(int n){
    return new Foo(*a+n);
}

void Foo::print(){
    printf("foo is =%i\n",*a);
}

int main(){
    Foo* bar = new Foo(1);
    delete bar;
    bar = new Foo(1);
    bar->add(1)->print();
}

Вывод:

destructor called
foo is =2

Проблема в том, что деструктор вызывается только один раз, а адрес, возвращаемый add(), теряется. Я могу уничтожить его, только если сначала сохраню его в переменной, а затем вызову деструктор, например:

Foo* temp = bar->add(1);
temp->print();
delete temp;

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

Итак, мой вопрос: есть ли способ вызвать деструктор возвращаемого объекта метода, если он разыменован, но не назначен какой-либо переменной? Чтобы деструктор в этом коде был правильно вызван?

bar->add(1)->print();

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Крис отвечает на конкретный пример, который вы предоставили.

Но нет никаких оснований использовать указатели в этом примере вообще.Код можно упростить до этого:

#include <iostream>

class Foo{
public:
    int a;

    Foo(int n);
    ~Foo();

    Foo add(int n);
    void print();
};

Foo::Foo(int n){
    a = n;
}

Foo::~Foo(){
    std::cout << "destructor called" << std::endl;
}

Foo Foo::add(int n){
    return Foo(a + n);
}

void Foo::print(){
    std::cout << "foo is =" << a << std::endl;
}

int main(){
    { Foo bar(1); }
    Foo bar(1);
    bar.add(1).print();
}
0 голосов
/ 10 мая 2018

Вы хотите использовать std::unique_ptr:

class Foo{
public:
    std::unique_ptr<int> a;
    Foo(int n);
    ~Foo();
    std::unique_ptr<Foo> add(int n);
    void print();
};

Foo::Foo(int n){
    a = std::make_unique(n);
}
Foo::~Foo(){
    printf("destructor called\n");
}
std::unique_ptr<Foo> Foo::add(int n){
    return std::make_unique<Foo>(*a+n);
}
void Foo::print(){
    printf("foo is =%i\n",*a);
}
int main(){
    auto bar= std::make_unique<Foo>(1);
    bar=std::make_unique<Foo>(1);
    bar->add(1)->print();
}
...