2013-03-15 138 views
0

我有以下代码:C++删除派生类被分配给所述基类的指针的指针

/* Example OOPBEI03.CPP */ 
#include <iostream> 

using namespace std; 

typedef char item; 

class stack 
{ 
private: 
    int p; 
protected: 
    item *st; 
public: 
    stack(int m=100) 
    { 
     st = new item[m]; 
     p = 0; 
    } 

    ~stack() 
    { 
     delete [] st; 
    } 

    void push(item v) 
    { 
     st[p++] = v; 
    } 

    item pop() 
    { 
     return st[--p]; 
    } 

    int empty() 
    { 
     return !p; 
    } 
}; 

class queue : public stack 
{ 
private: 
    int q; 
    item *qp; 
public: 
    queue(int m=50):stack(m) 
    { 
     q = 0; 
     qp = st; 
    } 

    ~queue() 
    { 
     delete qp; 
    } 

    item deque() 
    { 
     return qp[q++]; 
    } 
}; 

int main() 
{ 
    stack s(50); 
    queue q(20); 

    s.push('a'); 
    q.push('b'); 
    s.push('c'); 
    q.push('d'); 

    cout<<"pop "<<s.pop()<<endl; 
    cout<<"pop "<<s.pop()<<endl; 
    cout<<"deque "<<q.deque()<<endl; 
    cout<<"deque "<<q.deque()<<endl; 
    cout<<"empty queue? "<<q.empty()<<endl; 
    cout<<"empty stack? "<<s.empty()<<endl; 

    getchar(); 
    return 0; 
} 

我在主()在Visual Studio以下错误的端部得到:“调试断言失败!... _BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)“。

如果我在类队列或堆栈的析构函数中取消注释删除操作(我取消注释只有一个操作!),我没有问题。

我该如何解决这个问题?

+1

被删除我没有看到三/五规则被人跟踪。 – chris 2013-03-15 11:31:58

+2

首先阅读关于'虚拟'析构函数,然后讲述[三项规则](http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29),最后想一想当你尝试释放指针两次。 – 2013-03-15 11:35:35

+0

@all:谢谢你的回答。问题是,这个代码在我的学习书中。我现在在学校学习C++。 – 2013-03-15 20:58:11

回答

1

删除qp应该和新(它是我的术语)))相同。

delete [] qp; 
     ^^ 

但在这个特定的情况下,删除qp应该不惜一切

+0

类'stack'中的'delete []'似乎已经是这种形式。 – 2013-12-29 19:30:45

1

您正在删除栈基类和队列派生类中的指针。

让你的筹码类处理所有权,不要你应该让拷贝构造和拷贝赋值私人,否则处理它的方式(俗称“三原则”还删除它在队列

);否则,这些类可以很容易地在解精方式使用...


中的代码,不只是学习,只需使用std::stackstd::queue不是实现这些类自己

std::stackstd::queue是一流的具有可自定义的基础容器类型的模板

+0

实际上,只有队列的析构函数被调用,因为栈的构造函数不是虚拟的。它失败了,因为它应该使用delete [] qp。但我同意最好是让栈的析构函数虚拟化并让它处理删除操作。 – 2013-03-15 11:46:31

+0

@KristianDuske:在发布之前如何尝试这些东西? ;-)不是给定编译器的结果是任何*保证*,这是标准要求的内容,但它非常具有启发性。 – 2013-03-15 11:49:45

+0

对不起,你是对的。这两个desctructors被调用。我将确保我的评论在未来实际上是正确的! – 2013-03-15 11:57:22