解除引用时破坏对象

时间:2018-05-10 00:45:12

标签: c++ oop pointers dereference

我有这段代码......

#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 :(得分:1)

您想使用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();
}

答案 1 :(得分:1)

Chris的答案解决了您提供的特定示例。

但是,没有理由在该示例中使用指针。代码可以简化为:

#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();
}