-1

を使用してboost::ptr_vectorいますが、これは標準にも当てはまると思いますstd::vector。オブジェクトへのポインターをポリモフィックにboost::ptr_vector階層に配置しようとしていますが、次の行で作成されたEntityことを継承するということですObject

Object * newObject = new Entity(param1, param2);  // then I attempt to add it to the ptr_vector

しかし、プログラム (Visual Studio 2010) を中断して何が保持されているかを確認すると、ポインターがガベージからリダイレクトされることはなく、ガベージが保持されています。コードをステップ実行すると、パラメーター化されたコンストラクターに入り、正しい論理ステップに従います。

何がうまくいかないのかわからない。このポリモーフィックな動作を機能させるには、親または子に特定のメンバー関数が必要ですか (現在、すべての子には、その型に固有のパラメーター化されたコンストラクターと、ポリモーフィックな相互作用メソッドと共にデストラクタがあります)。代入演算子が必要か、Objectクラスにコンストラクターが必要か。

operator への呼び出しがnewオブジェクトに解決されていないようですが、別のものに解決されているようですが、VS2010 はエラーをスローしていません。


編集:何が起こっているべきかの説明。

2D std::vector(長方形/非ギザギザ) のステップスルー

case/switch生成され、構造に追加されるオブジェクトを決定するために使用

Object へのポインタが作成され、new に割り当てられます // ここで問題が発生していると思います

次に、そのポインターの参照がマネージャーメンバーにプッシュされますboost::ptr_vector

Visual Studio 2010 では、ポインターを作成する行に区切りを入れ、新しい (ポリモーフィック) を割り当て、ポインターpush_back()boost::ptr_vector監視する行に 1 つ割り当てます。一時ポインター値が作成され、コンストラクターにステップインすると、そのコンストラクターのすべての論理ステップに従います。コンストラクターが終了し、スタックがコンストラクターを呼び出した行に戻ると、ポインターは同じ値のままです (これは許容されます)、しかし、それがすべての値を指しているオブジェクトを見ると、(静的に構成されたメンバー オブジェクトを含む) 疑問符として表示されます。次に、プッシュバックがトリガーされ、ブーストヘッダーに入ると、x値に同じ情報が表示されます。

ポインターが作成され、オブジェクトのデータが作成されているように見えますが、コンストラクターが終了すると、実際には親クラス オブジェクトに値が割り当てられません。

問題のあるヘッダーの例 (実際のヘッダーにはメンバー変数があり、それらの実装は別の cpp ファイルにあります):

class Object{
public :
    virtual void interact(int action, Object& source){}
    virtual void updateObject(float duration){}
    virtual ~Object(){}
    bool operator==(const Object& _other)const;
    bool operator!=(const Object& _other)const;
};

class Entity : public Object{
public:
    Entity(Vector3 location, Type thisType, SpecialType difficulty=noSpecial);
    ~Entity();
    void interact(int action, Object& source);
    void updateObject(float duration);
};

編集:コンテキストを変更して、目前の問題をより適切にターゲットにし、解決策を受け取ります

4

3 に答える 3

1

ポインター値は、コンストラクターが終了した後にのみ変更されます。問題はありません。最初に一時ポインターが作用し、それのみがポインターに割り当てられるため、論理的です。

于 2012-04-25T16:44:37.870 に答える
1

Object * newObject = new Entity(param1, param2);

新しく作成されたオブジェクトをnewObject指すようになります。コンストラクターの実行中は、newObjectまだ割り当てられていません。あなたがその後持っている場合例えば

vec.push_back(newObject);

メソッドに足を踏み入れるpush_backと、引数がメソッドを参照Objectする仮想テーブルを持っていることがわかりEntityます。(少なくとも仮想デストラクタはありますよね?)

于 2012-04-25T18:07:29.713 に答える
0

あなたが投稿した内容に基づいて、問題がどのように発生したか/どのように修正するかは言うまでもなく、問題を確認することは (可能であれば) 困難です。

おそらく、実際に機能するものから始めて、必要な機能を追加するか、少なくとも期待されているもの/機能するものから逸脱している場所を把握することをお勧めします。そこで、オブジェクトを動的に作成し、それらを に入れptr_vector、それぞれで仮想関数を使用してコンテナの内容が期待どおりであることを確認し、コンテナをスコープ外に出す (そしてその過程でオブジェクトを破棄する) という小さなサンプルを次に示します。含まれるポインターによって参照されるオブジェクト)。

#include "boost/ptr_container/ptr_vector.hpp"
#include <iostream>
#include <string>
#include <sstream>

class Object { 
    std::string name;
public:
    Object(std::string const &n) : name(n) {}

    virtual std::ostream &write(std::ostream &os) const {
        return os << name;
    }

    virtual ~Object() { std::cout << "Object being destroyed\n"; }
};

class Entity : public Object { 
    int value;
public:
    Entity(int v, std::string name) : Object(name), value(v) {}

    std::ostream &write(std::ostream &os) const { 
        return os << "Entity: " << value;
    }
    ~Entity() { std::cout << "Entity being destroyed\n"; }  
};

int main() { 
    boost::ptr_vector<Object> objects;

    for (int i=0; i<10; i++) {
        std::stringstream name;
        name << "object: " << i;
        if (i & 1)
            objects.push_back(new Object(name.str()));
        else
            objects.push_back(new Entity(i, name.str()));
    }

    boost::ptr_vector<Object>::iterator pos;
    for (pos = objects.begin(); pos != objects.end(); pos++) {
        pos->write(std::cout);
        std::cout << "\n";
    }
    return 0;
}

少なくとも私にとっては、出力は次のようになります。

Entity: 0
object: 1
Entity: 2
object: 3
Entity: 4
object: 5
Entity: 6
object: 7
Entity: 8
object: 9
Entity being destroyed
Object being destroyed
Object being destroyed
Entity being destroyed
Object being destroyed
Object being destroyed
Entity being destroyed
Object being destroyed
Object being destroyed
Entity being destroyed
Object being destroyed
Object being destroyed
Entity being destroyed
Object being destroyed
Object being destroyed

価値があるのは、デストラクタに注意してください- anObjectが破棄されると、ベース dtor のみが呼び出されますが、 anEntityが破棄されると、最初に派生 dtor が呼び出され、次にベース dtor が呼び出されます (したがって、両方の 'エンティティが破棄されていることがわかります' および '破棄されるオブジェクト")。

于 2012-05-04T14:30:43.673 に答える