删除对象时 C++ 断言错误 [英] C++ assertion error while deleting object

查看:37
本文介绍了删除对象时 C++ 断言错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有奇怪的断言错误,我找不到这段代码有什么问题.

I have strange assertion error and I can not find what is wrong with this code.

断言表达式是_BLOCK_TYPE_IS_VALID(pHead->nBlockUse).

Assertion expression is _BLOCK_TYPE_IS_VALID(pHead->nBlockUse).

为了更好的可读性,我稍微简化了代码.

I simplified code a bit for better readability.

class Creator
{
public:
    virtual ~Creator()
    {
        for (MyObject* item : _list)
        {
            delete item; <-- assertion error here
            item = 0;
        }
        _list.clear();
    }

    template <class T>
    T& create()
    {
        T * item = new T();
        _list.push_back(item);
        return *item;
    }

private:
    std::list<MyObject*> _list;
};

class A : public MyObject, public Creator
{
};

class B : public MyObject, public Creator
{
};

int main()
{
    A a;
    a.create<A>();
} <-- call of destructor

这个想法是一个对象女巫继承了 Creator,可以创建任何其他对象,并持有指向这些对象的指针.而程序员可以使用引用.当超级"对象被销毁时,所有子"对象也被销毁.

The idea is that an object witch inherits Creator, can create any other object, and hold pointers to those objects. While programmer can work with references. And when "super" object is destroyed, all "sub" objects are destroyed too.

如果我改为:

template <class T>
class Creator
{
public:
    virtual ~Creator()
    {
        for (T* item : _list)
        {
            delete item;
            item = 0;
        }
        _list.clear();
    }

    T& create()
    {
        T * item = new T();
        _list.push_back(item);
        return *item;
    }

private:
    std::list<T*> _list;
};

class A : public MyObject, public Creator<A>
{
};

class B : public MyObject, public Creator<B>
{
};

int main()
{
    A a;
    a.create();
}

现在 create 方法只创建一种类型的对象(本例中的对象 A).但我需要,那个 create 方法可以创建任何继承 MyObject 的对象.就像代码的第一次平静一样.

Now create method creates only one type of object ( object A in this example ). But I need, that create method could create any object that inherits MyObject. Like in first peace of code.

对此断言错误的任何帮助将不胜感激.谢谢.

Any help for this assertion error would be appreciated. Thanks.

推荐答案

问题是您的 MyObject 类缺少虚拟析构函数,并且您试图在指向派生对象的指针上调用 delete类使用指向基类 MyObject 的指针.如果基类析构函数不是虚拟的,则通过基类指针在派生对象上发出 delete 是未定义的行为.

The issue is that your MyObject class lacks a virtual destructor, and you're attempting to call delete on a pointer to the derived class using a pointer to the base class MyObject. Issuing a delete on a derived object through a base class pointer is undefined behavior if the base class destructor is not virtual.

5.3.5 删除(第 3 段)

5.3.5 Delete (Paragraph 3)

在第一个选择中(删除对象),如果静态类型的操作数与其动态类型不同,静态类型应为操作数动态类型的基类并且静态类型应具有虚拟析构函数或行为未定义.

In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual destructor or the behavior is undefined.

在基类 MyClass 中将析构函数设为虚拟后,以下内容将在 Visual Studio 2013 中正常工作:

Once the destructor is made virtual in the base class MyClass, the following works correctly in Visual Studio 2013:

#include <list>
struct MyObject 
{
    virtual ~MyObject() {}
};

class Creator
{
public:
    virtual ~Creator()
    {
        for (MyObject* item : _list)
        {
            delete item; 
            item = 0;
        }
        _list.clear();
    }

    template <class T>
    T& create()
    {
        T * item = new T();
        _list.push_back(item);
        return *item;
    }

private:
    std::list<MyObject*> _list;
};

class A : public MyObject, public Creator
{
};

class B : public MyObject, public Creator
{
};

int main()
{
    A a;
    a.create<A>();
} 

这篇关于删除对象时 C++ 断言错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆