2
struct Abstract{
    virtual void methodA() = 0;
};

struct Test : public Abstract{
    virtual void methodA(){
        printf("Test message");
    }
};

class Foo{
    Abstract* abs; //I made it this way so that an instance of Foo 
                   //can easily switch between any class that implements 
                   //Abstract
public:
    virtual ~Foo(){
        delete abs; //free abs
    }

    void setAbs(Abstract* a){
        abs = a; //is there any other way to do this?
    }

    void changeAbs()//method to switch abs

    void show(){
        abs->methodA();
    }
};

int main(){
    Test *test = new Test();
//    Test test; //local instantiation will throw a segmentation fault
               //because abs is freed in the desctructor of Foo
    Foo foo;
    foo.setAbs(test);
    foo.show();

//    delete test; //using a pointer is fine unless freed
    return 0;
}

我的担忧是:

  1. 如果我没有在析构函数中释放 abs 并且用户忘记释放他的实现 Abstract 的对象,或者如果用户这样做setAbs(new Test()),就会有泄漏。

  2. 如果我在析构函数中释放 abs ,如果用户在本地实例化Test或者他使用指针并最终自己删除它,它将引发分段错误。

  3. Abstract abs也不允许,因为它是一个抽象类

我想将 setAbs() 更改为如下内容:

void setAbs(Abstract* a){
    abs = new Abstract(*a); //but copying like a normal class doesn't work on abstract classes
}  

我的问题是,有没有其他方法可以实现 setAbs() 以便复制传递的参数?

如果没有其他办法,我会让释放成为用户的工作。

4

1 回答 1

4

这里的根本问题是你没有明确谁拥有这个内存。

如果你的类拥有它,那么在你的析构函数中释放是安全的。好吧,不是你写的方式,而是理论上。阅读三法则

如果您的类不拥有该指针,那么请不要释放它。解除分配不是你的,所以使用它,不要再做。

处理记忆的安全方法是隐含地执行关于谁负责什么的合同。如果用户继续使用delete您的指针,那么,告诉他们停止;这不关他们的事。你可以使用std::unique_ptr指针和get()函数来做同样的事情。上课不会阻止你,怎么可能?它不在乎你是否从自己的脚上开枪。实时调频。

Speaking of std::unique_ptr... why aren't you using it (or std::shared_ptr if appropriate)? This is a solved problem, no need to come up with your own solution here.

于 2013-03-07T04:10:51.253 回答