2

次のように定義されたクラスがあります。

Class A
{
public:
    int num;
    A *parent;
    vector<A *> children;
    ...

    // constructor without parameters
    A(void)
    {
        this->num = 3;
        this->parent = 0;
        for (int i=0;i<num;++i)
            children.push_back(new A(this,num-1));
    }

    // constructor with parameters
    A(A *a,int n)
    {
        this->num = n;
        this->children->parent = a;
        for (int i=0;i<num;++i)
            this->children.push_back(new A(this,this->num-1));
    }
};

これで、コンストラクターは正常に動作します。デストラクタに問題があります。現在、デストラクタは次のように定義されています。

A::~A(void)
{
    if (this->parent!=0) this->parent = 0;
    for (int i=0;i<(int)children.size();++i)
        this->children[i]->~A();
    vector <A *> ().swap(this->children);
}

しかし、デバッグするたびに、次の場所で壊れます。

void deallocate(pointer _Ptr, size_type)
    {    // deallocate object at _Ptr, ignore size
    ::operator delete(_Ptr);
    }

this->children のベクトル内のポインターを削除できないようですが、クラスを正常に分解できる方法はありますか?

4

3 に答える 3

5

デストラクタは次のようにする必要があります。

A::~A(void)
{
    for (size_t i=0; i < children.size(); ++i)
        delete children[i];
}

おそらく、コピー コンストラクターも調べる必要があります。そうしないと、次のようなコードは失敗します。

{
    A foo;
    B bar = foo;
}

同じポインターを 2 回削除するためです。

次の 2 つの投稿のいずれかが、12を理解するのに役立つ場合があります。

于 2012-06-01T15:28:17.900 に答える
1

A のデストラクタでは、子アイテムのデストラクタを明示的に呼び出すべきではなく、ベクターの要素を削除するだけです。これはあなたの目的には十分なはずです:

A::~A(void)
{
    for (size_t i=0; i<children.size(); ++i)delete children[i];
}
于 2012-06-01T15:27:39.777 に答える
0

パラメーターを持つコンストラクターにはタイプミスのバグがあります-ポインターでもメンバーでもないため、this->children->parentコンパイラーになりません。代わりに使用するつもりだったのではないかと思います。childrenvectorparentthis->parent

デストラクタは、各子オブジェクトのデストラクタを直接呼び出しています。これにより、子は破棄されますが、メモリは解放されません。演算子を使用して子オブジェクトを割り当てるため、演算子を使用してデストラクタを呼び出し、メモリを正しく解放するnew必要があります。delete

ちなみに、あなたのnumメンバーは冗長です。children.size()必要なところならどこでも使えnumます。

代わりにこれを試してください:

class A 
{ 
private:
  static const int default_num = 3;

public: 
    A *parent; 
    vector<A *> children; 
    ... 

    // default constructor
    A() 
    { 
        parent = 0; 
        for (int i = 0; i < default_num; ++i) 
            children.push_back(new A(this, default_num-1)); 
    } 

    // constructor with parameters 
    A(A *a, int n) 
    { 
        parent = a; 
        for (int i = 0; i < n; ++i) 
            children.push_back(new A(this, n-1)); 
    } 

    ~A()  
    {  
        parent = 0;  

        for (vector<A *>::size_type i = 0; i < children.size(); ++i)  
            delete children[i];  
        /*
        alternatively:
        for (vector<A *>::iterator i = children.begin(); i != children.end(); ++i)  
            delete *i;  
        */

        children.clear(); // optional, will be handled when vector is implicitally destructed
    }  
};
于 2012-06-01T19:10:51.317 に答える