2013-04-10 24 views
1

可以删除抽象类而不是孩子吗?是否所有的分配都会被解除分配?可以删除抽象类而不是孩子吗?

考虑一个下列情形作为一个例子,但请不要限制你的答案是一个案例:

struct A { 
    virtual void fun() = 0; 
}; 
struct B : public A { 
    void fun() { /* actually doing something here. */ } 
}; 
struct C { 
    A *a; 
    void OneTask() { 
     // (...) 
     a = new B(); 
    } 
    void AnotherTask() { /* using fun() in some way. */ } 
    ~C() { delete a; } 
}; 

的想法是有OneTask的多个可能的结果(),它导致的分配指向从A继承的不同类的指针,B仅仅是一个例子;然后在AnotherTask()和C类

+1

你应该阅读有关[当使用虚拟析构函数(http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors)。 – Joe 2013-04-10 20:03:17

+0

为什么'struct A'? – Dariusz 2013-04-10 20:03:49

+1

@Dariusz:为什么不呢? – 2013-04-10 20:05:16

回答

2

的其他方法合理使用这样的结果,您必须在基类派生其他类的完全破坏虚析构函数不会发生。

struct A { 
    virtual void fun() = 0; 
virtual ~A() 
    { 
    } 
}; 
+0

我理解并承担在我的心脏,但会被完全破坏真失败,甚至对我的简单的例子? – yauser 2013-04-10 20:14:10

+0

是的,它会失败。您可以通过定义析构函数并添加“cout”消息来进行验证。你可以观察到派生类析构函数没有被调用。 – shivakumar 2013-04-10 20:21:20

+0

形式上,如果通过指针删除派生类型的一个目的是不具有虚析构函数的基座的行为是未定义。 – 2013-04-10 20:34:44

1

是的,这是完全罚款delete a不知道什么实际派生类型a指向。

由于Shivakumar宣读指出,如果你不把你的基类的析构函数虚拟的,然后删除派生类不会最终调用基类的析构函数。在你的微不足道的例子中,这不是一个问题,但在现实生活中,你应该总是让你的析构函数变成虚拟的。

0

如果A有一个虚析构函数,然后A和B两个析构函数被成功地称为(第一B,则A),

如果不声明为虚拟的,那么只有A的析构函数的构造函数是在删除期间调用B和扩展数据可能会泄漏。

struct A { 
    virtual void fun() = 0; 
    virtual ~A(); 
}; 
struct B : public A { 
    void fun() { /* actually doing something here. */ } 
    ~B(); 
}; 
+0

但是如果我不在子类中添加任何更多的字段,只有新的方法,那么没有泄漏是可能的,对吗? – yauser 2013-04-11 22:39:12

+0

@yauser是的,这是正确的,但也不能像任何用途一样使用B的析构函数来终止某些操作。 – 2013-04-12 04:43:58

相关问题