0

抽象クラスと2つの具象サブクラス(Store)があり、どちらも抽象クラス(Factory)から派生した別の具象サブクラスへのポインターがあります。以下はストアのコードです。メモリリークを防ぎたかったので、コピーコントロールを書き始めました。ただし、新しいファクトリをインスタンス化することはできません。これは、どのタイプになるかを事前に知らないためです。これを回避するための良い習慣は何ですか?具体的なストアにコピーコントロールを記述できましたが、コードが重複しています。代わりにスマートポインタを使って作業しようとしましたが、別の問題があります。スニペットmyFactory = std::make_shared<AbstractFactory>(ConcreteFactoryA());は明らかに最初にAbstractFactoryを作成し、次にそれをConcreteFactoryAで埋めます。ただし、名前が示すように、コンパイラが教えてくれるように、AbstractFactoryをインスタンス化することはできません。shared_ptrsを抽象クラスで使用できますか?

プレーンポインタを使用したコード:

#pragma once
#include "AbstractFactory.h"

class AbstractStore
{
public:
    // Copy control
    AbstractStore(const AbstractStore& orig) : myFactory(new AbstractFactory(orig.myFactory)) {}
    AbstractStore& operator=(const AbstractStore& orig) { return *this; } // TODO
    ~AbstractStore(void) {}
protected:
    // Constructor
    AbstractStore(void) {}
    // Data members
    AbstractFactory* myFactory;
};

class ConcreteStoreA : public AbstractStore
{
public:
    ConcreteStoreA(void) { myFactory = new ConcreteFactoryA; }
    ~ConcreteStoreA(void) {}
};

class ConcreteStoreB : public AbstractStore
{
public:
    ConcreteStoreB(void) { myFactory = new ConcreteFactoryB; }
    ~ConcreteStoreB(void) {}
};

スマートポインタを使用したコード:

#pragma once
#include "AbstractFactory.h"
#include <memory>

class AbstractStore
{
public:
    // Copy control
    AbstractStore(const AbstractStore& orig) : myFactory(orig.myFactory) {}
    AbstractStore& operator=(const AbstractStore& orig) { myFactory = orig.myFactory; return *this; }
    ~AbstractStore(void) {}
protected:
    // Constructor
    AbstractStore(void) {}
    // Data members
    std::shared_ptr<AbstractFactory> myFactory;
};

class ConcreteStoreA : public AbstractStore
{
public:
    ConcreteStoreA(void) { myFactory = std::make_shared<AbstractFactory>(ConcreteFactoryA()); }
    ~ConcreteStoreA(void) {}
};

class ConcreteStoreB : public AbstractStore
{
public:
    ConcreteStoreB(void) { myFactory = std::make_shared<AbstractFactory>(ConcreteFactoryB()); }
    ~ConcreteStoreB(void) {}
};
4

2 に答える 2

2

make_shared正しく使用していません。使用する:

std::make_shared<ConcreteFactory>();

ここでは引数なしで呼び出します。make_sharedは構築されたオブジェクトを受け入れませんが、そのコンストラクターに転送される引数を受け入れます。あなたの場合、抽象階層ではうまく機能しないコピーコンストラクターに転送することになります。階層内にコピー可能なオブジェクトが必要な場合はclone、共変の戻り型を持つメンバー関数を使用してください。

shared_ptr<ConcreteFactory>これにより、割り当てで変換されるが返されます(ここshared_ptr<AbstractFactory>の(9)を参照してください。また、コンストラクタ初期化子リストと仮想デストラクタを使用します。

于 2012-07-16T09:29:32.357 に答える
0

スマートポインタアプローチを機能させるには、おそらく次の2つのいずれかが必要です。

  1. またはを作成ConcreteFactoryAしてConcreteFactoryB返します。「ストア」クラスに割り当てるか、さらには初期化するだけです。std::shared_ptr<AbstractFactory>std::unique_ptr<AbstractFactory>

  2. またはコンストラクターshared_ptr<>を使用して生のポインターからsを初期化しますstd::shared_ptr<>::reset

通常は、rawポインターで使用std::make_shared<>するスマートポインターでのみ使用します。newあなたの場合、あなたは単にポインタを割り当てているだけなので、それを使うべきではありません。

于 2012-07-16T09:33:19.817 に答える