【问题标题】:c++ delete pointer of a derived class which is assigned to a pointer of the base classc ++删除派生类的指针,该指针分配给基类的指针
【发布时间】:2013-03-04 02:26:17
【问题描述】:

我有以下代码:

/* 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 中的 main() 末尾出现以下错误:“调试断言失败!... _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)”。

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

我该如何解决这个问题?

【问题讨论】:

  • 我没有看到遵循三/五的规则。
  • 首先阅读 virtual 析构函数,然后阅读 the rule of three,最后想想当您尝试释放指针两次时会发生什么。
  • @all:感谢您的回答。问题是,这段代码在我的学习书中。我现在在学校学习 C++。

标签: c++ visual-studio pointers


【解决方案1】:

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

让你的堆栈类处理所有权,不要在队列中也删除它

顺便说一句,您应该将复制构造和复制分配设为私有,或者处理它(称为“三规则”);否则这些类很容易被用在不好的地方......


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

std::stackstd::queue 是具有可自定义底层容器类型的类模板

【讨论】:

  • 其实只有队列的析构函数被调用,因为栈的构造函数不是虚拟的。它失败了,因为它应该使用 delete [] qp。但我同意最好将堆栈的析构函数设为虚拟并让它处理删除。
  • @KristianDuske:在发帖之前尝试一下这些东西怎么样? ;-) 并不是说​​使用给定编译器的结果是标准要求的任何保证,但它具有很强的建议性。
  • 对不起,你是对的。两个析构函数都被调用。以后我会确保我的cmets真的是正确的!
【解决方案2】:

删除qp应该和newing一样(这是我的术语)))。

delete [] qp;
       ^^

但在这种特殊情况下,删除 qp 应该完全删除

【讨论】:

  • delete[] 类中的 stack 似乎已经是这种形式。
猜你喜欢
  • 2021-09-09
  • 1970-01-01
  • 2017-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多