指针和抽象类

时间:2013-03-07 04:07:33

标签: c++ c pointers abstract-class

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也是不允许的,因为它是一个抽象类

  4. 我想将setAbs()更改为:

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

    我的问题是,有没有其他方法来实现setAbs(),以便它将传递参数的副本?

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

1 个答案:

答案 0 :(得分:4)

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

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

如果您的班级拥有指针,那么,请不要取消分配它。解除分配并不属于您,所以请使用它,不要再使用它。

处理内存的安全方法是隐式执行合同,确定谁负责什么。如果用户继续前进,delete指针,那么告诉他们停止;这不是他们的事。您可以使用std::unique_ptr指针和get()函数执行相同操作。班级不会阻止你,怎么可能?如果你自己拍脚,它并不在乎。 RTFM。

说到std::unique_ptr ...为什么不使用它(或std::shared_ptr如果合适的话)?这是一个已解决的问题,无需在此处提出您自己的解决方案。