不同的析构函数类型?

时间:2014-02-15 23:29:44

标签: c++ copy destructor

我有一个名为Chunk的对象,它包含一个指向b2Body的指针。它做了其他重要的事情,但我为了简单起见删除了它们。抬头,智能指针不起作用(我想),你会明白为什么。

class DChunk
{
public:
    DChunk();

    DChunk(const DChunk& old);
    virtual ~DChunk();

    virtual b2Body* getBody() const;

private:
    b2Body* m_pBody;//pointer;
};

问题是,如何定义何时删除m_pBody对象。

如果我想要复制这个对象,就像说有这些东西的向量而我push_back另一个,它将调用复制构造函数,复制m_pBody的内存地址(这就是我想要的),然后删除旧的一。如果此对象上的析构函数删除了m_pBody,那显然很糟糕,因为新副本没有有效的内存地址,但是如果它没有删除它,那么m_pBody将永远不会被删除,并且当没有删除时需要删除它更多Chunks指着它。

删除m_pBody对象的唯一正确方法是调用m_pBody-> GetWorld() - > DestroyBody(m_pBody);这不是我的控制,所以聪明的指针不能真正起作用。 我希望有不同类型的析构函数可以被适当调用,比如在向量中创建副本时。此外,如果有帮助的话,一个b2Body永远不应该有多个Chunk。

3 个答案:

答案 0 :(得分:1)

我会假设你有像

这样的东西
    vector<DChunck> myvec;

你担心做什么

    obj=DChunk()
    myvec.push_back(obj)

首先(这是非常适合初学者的方法,避免使用智能指针或任何C ++ 11),创建容器DChunk对象的方法并不完全正确。那是因为当你宣布

    vector<DChunk>

你告诉你的向量它将接收大小为DChunk的对象。 但是,由于该类包含指向数组的指针,m_pBody(数组的大小不会是常量!),这种方法对于C ++来说不会太“健康”。 鉴于此,您可以做其他事情,坚持您的类设计:创建一个指针容器! 你可以创建

    vector<DChunk*> myvec;

如果你想将一个对象添加到该向量,你只需要

    DChunk *obj = new DChunk();
    myvec.push_back(event);

因为现在容器正在处理指针,这些指针可以在不干扰对象内容的情况下被处理,避免了对析构函数的担忧。 现在,调用对象的方法将是

    (*myvec[3]).getBody()

或(清洁版)

    myvec[3]->getBody()

希望我能解决你的问题

答案 1 :(得分:0)

你也可以提供移动构造函数,这样代替复制,它就会移动东西......这是我几个小时前做的一个例子,因为我遇到了同样的问题(我不知道这些构造函数的顺序是什么当被调用时,“&amp;&amp;”也就是移动构造函数):

移动构造函数类似于复制构造函数。区别在于移动构造函数而不是复制值和东西,您将给定对象的指针(不是复制)和值分配给新的(this-&gt; temp = OldClass.temp),然后使OldClass.temp = NULL;这样当调用不可避免的析构函数时,它会找到一个NULL指针并且不会删除它。

#include <iostream>
#include <Windows.h>

class MyClass
{
public:
    MyClass()
    {
        temp = new RECT();
        ZeroMemory(temp, sizeof(RECT));
    }
    MyClass(int x, int y)
    {
        temp = new RECT();
        ZeroMemory(temp, sizeof(RECT));
        temp->left = x;
        temp->top = y;
    }
    MyClass(MyClass &&OldClass)
    {
        if (this->temp != NULL)
        {
            delete this->temp;
            this->temp = NULL;
        }
        temp = OldClass.temp;
        OldClass.temp = NULL;
    }
    MyClass& operator=(MyClass &&OldClass)
    {
        if (this->temp != NULL)
        {
            delete this->temp;
            this->temp = NULL;
        }
        temp = OldClass.temp;
        OldClass.temp = NULL;
        return *this;
    }
    MyClass(const MyClass &OldClass)
    {
        *temp = *OldClass.temp;
    }
    MyClass& operator=(const MyClass &OldClass)
    {
        *temp = *OldClass.temp;
        return *this;
    }
    ~MyClass()
    {
        if (this->temp != NULL)
        {
            delete this->temp;
            this->temp = NULL;
        }
    }
    void Print()
    {
        std::cout << temp << " " << temp->left << " " << temp->top << " " << temp->right << " " << temp->bottom << '\n';
    }
private:
    RECT *temp;
};

int main()
{
    MyClass bla, cha(54, 48);
    bla.Print();
    cha.Print();
    bla = MyClass(2, 2);
    bla.Print();
    bla = cha;
    bla.Print();
    cha = MyClass(54, 2);
    cha.Print();
    std::cin.get();
    return 0;
}

答案 2 :(得分:0)

通常,适当的内存管理是非常重要的任务,并且不存在普遍的决策。一些简单和常见的众所周知的方法在最新的库中被称为“智能指针”类型(您也可以自己定义它们(通过复制已知的“标准定义”))。但它也不是一个完全普遍的:-) 而你的问题似乎是这种普遍解决方案的问题。 其他一些编程语言(java ...,而不是C ++)告诉你要解决这个问题(通过内置的语言实现方法)。 你写道:“此外,如果有帮助的话,一个b2Body不应该有多个Chunk。” 。然后问题似乎消失了(因为Chunk根本无法复制)。 (?)