指针和抽象类

Pointer and Abstract class

本文关键字:抽象类 指针      更新时间:2023-10-16
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((,从而使参数的副本通过?

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

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

如果你的类拥有它,那么在析构函数中释放它是安全的。不是你写的那样,而是理论上的。阅读《三条规则》。

如果你的类不拥有指针,那么,好吧,不要解除分配。解除分配不是你的,所以使用它,不要再做任何事情。

处理内存的安全方法是隐式地强制执行一个关于谁对什么负责的契约。如果用户继续并且delete是你的指针,那么,告诉他们停止;这不关他们的事。您可以使用std::unique_ptr指针和get()函数来执行同样的操作。这堂课不会阻止你,怎么可能呢?它不在乎你是否开枪自杀。RTFM。

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