1

基本クラス、2つの派生クラス、および派生オブジェクトを指す基本ポインターのコンテナーを持つentitymanagerクラスがあります。派生クラスのコピーコンストラクターを処理するための仮想クローンメソッドがベースにありますが、代入演算子のオーバーロードとスライスの防止に頭を悩ませているので、誰かがそれを手伝ってくれて、おそらくiveがどのように処理したかを確認してくださいentitymanagerコピーコンストラクター?大丈夫だと思います

class System
{
public:
    virtual System* clone()=0;
};

class projectile :public System
{
public:
    projectile* clone()
    {
        return new projectile(*this);
    }
};

class player : public System
{
public:
     player* clone()
    {
        return new player(*this);
    }
};

class EntityManager
{
private:
    vector<System*> theEntities;
public:
    EntityManager(){}
    EntityManager(EntityManager& other)
    {
        for (size_t i=0;i<other.theEntities.size();i++)
            theEntities.push_back(other.theEntities[i]->clone());
    }
    void init()
    {
        projectile* aProjectile = new projectile;
        player* aPlayer = new player;
        theEntities.push_back(aProjectile);
        theEntities.push_back(aPlayer);
    }
};

int main (int argc, char * const argv[]) 
{
    EntityManager originalManager;
    originalManager.init();
    EntityManager copyManager(originalManager);

    return 0;
}
4

1 に答える 1

3

コンテナーを交換するメンバーを追加してswapから、コピーおよび交換として割り当てを実装します。

void swap(EntityManager& other)
{ theEntities.swap(other.theEntities); }

EntityManager& operator=(EntityManager other)
{ swap(other); return *this; }

代入演算子の引数は、既に作成したコピーコンストラクターを使用してコピーされ、データを交換するため、*thisそのパラメーターがスコープ外になると、属していたデータが破棄さ*thisれ、新しくコピーされたデータが所有されます。

このようにコピーコンストラクターを再利用するということは、正しいコピーコンストラクター(および通常は正しく取得するのが簡単な正しいスワップ)を実装するだけでよく、代入演算子は本当に単純で自動的に正しいことを意味します。

注意init:メンバーとコピーコンストラクターは例外セーフではありません。いずれかのpush_back操作で例外がスローされた場合、メモリリークが発生します。デストラクタもありませんが、実際のコードにはそれが含まれていると思います。

于 2012-06-09T12:44:58.330 に答える