2

これらの C++ クラスを次のように定義しています。

class A
{
public:
    B *createB();
};

class B 
{
public:
    virtual void fun() = 0;
};
class B1 : B {/* ... */};
class B2 : B {/* ... */};

したがって、基本的に B は抽象クラスであり、B1 と B2 は B の具体的な実装であり、A はコードのどこかに B 型のインスタンスを作成します。A は factoryではなく、A::createB単なる例であることに注意することが重要です。

A の初期化中に B のサブクラスを渡すことができるようにしたいので、実行時に必要に応じて後者によって前者のインスタンスを作成できます。例:

A *a1 = /* sorcery here */;
A *a2 = /* another magic code */;

a1->createB(); // getting B1
a2->createB(); // getting B2

それを達成するための最良の方法は何ですか?テンプレートを使わなくても可能ですか?


回答に基づいて、私はこれに行き着きました。ありがとう!

class B
{
public:
    virtual void fun() = 0;
    virtual B *clone() = 0;
};

class B1 : public B
{
public:
    virtual void fun()
    {
        std::cout << "B1" << std::endl;
    }
    virtual B *clone()
    {
        return new B1();
    }
};

class B2 : public B {/* analogous to B1 */};

class A
{
public:
    A(B *b) : b(b) {};

    B *createB()
    {
        return b->clone();
    }
private:
    B *b;
};

A(new B1()).createB()->fun(); // prints "B1"
A(new B2()).createB()->fun(); // prints "B2"
4

3 に答える 3

4

clone()B でメソッドを実装します。

B*作成時に a を A に渡します。clone()A はそれB*をパラメータとしてB を呼び出します。

クローニングの詳細については、C++ でクローンを使用する状況とその使用方法に関する質問を参照してください。, C++ での clone() の最適なシグネチャは? クローンメソッドを簡単に書く方法は? 、とりわけ。

于 2013-11-06T13:28:19.647 に答える
2

これを実現するには、 Prototypeデザイン パターンを使用できます。またはAのインスタンスを渡し、次のようにメンバー関数を に追加します。B1B2clone()B

class B 
{
public:
    virtual void fun() = 0;
    virtual B* clone() = 0; // B1::clone returns new B1; B2::clone returns new B2
};

AB後で使用するために、初期化中に渡された のプロトタイプ インスタンスを格納します。B後で新しいものを作成する必要がclone()ある場合、プロトタイプを呼び出して適切なクラスのインスタンスを取得します。

于 2013-11-06T13:30:30.730 に答える
0

abstract factoryが必要なようです。

ここで例を見ることができます:

#include <iostream>
#include <string>

class Window
{
protected:
int width;
int height;
std::string toolkit;
std::string type;

Window(std::string usedToolkit, std::string windowType)
: toolkit(usedToolkit), type(windowType)
{}

public:
std::string getToolkit()
{
return toolkit;
}

std::string getType()
{
return type;
}
};

class GtkToolboxWindow : public Window
{
public:
GtkToolboxWindow()
: Window("Gtk", "ToolboxWindow")
{}
};

class GtkLayersWindow : public Window
{
public:
GtkLayersWindow()
: Window("Gtk", "LayersWindow")
{}
};

class GtkMainWindow : public Window
{
public:
GtkMainWindow()
: Window("Gtk", "MainWindow")
{}
};


class QtToolboxWindow : public Window
{
public:
QtToolboxWindow()
: Window("Qt", "ToolboxWindow")
{}
};

class QtLayersWindow : public Window
{
public:
QtLayersWindow()
: Window("Qt", "LayersWindow")
{}
};

class QtMainWindow : public Window
{
public:
QtMainWindow()
: Window("Qt", "MainWindow")
{}
};


/* This is the abstract factory. */
class UIFactory
{
public:
virtual Window* getToolboxWindow() = 0;
virtual Window* getLayersWindow() = 0;
virtual Window* getMainWindow() = 0;

};

/* Factory for Gtk toolkit */
class GtkUIFactory : public UIFactory
{
public:
Window* getToolboxWindow()
{
return new GtkToolboxWindow();
}

Window* getLayersWindow()
{
return new GtkLayersWindow();
}

Window* getMainWindow()
{
return new GtkMainWindow();
}
};

/* Factory for Qt toolkit */
class QtUIFactory : public UIFactory
{
public:
Window* getToolboxWindow()
{
return new QtToolboxWindow();
}

Window* getLayersWindow()
{
return new QtLayersWindow();
}

Window* getMainWindow()
{
return new QtMainWindow();
}
};

int main()
{
UIFactory* ui = 0;

/* Check what environment is running
and create appropriate factory. */
if (/* Gtk == */ true)
{
ui = new GtkUIFactory();
}
else
{
ui = new QtUIFactory();
}

/* Use the factory to build interface. */
Window* toolbox = ui->getToolboxWindow();
Window* layers = ui->getLayersWindow();
Window* main = ui->getMainWindow();

/* See what have we recieved. */
std::cout << toolbox->getToolkit() << ":"
<< toolbox->getType() << std::endl;

std::cout << layers->getToolkit() << ":"
<< layers->getType() << std::endl;

std::cout << main->getToolkit() << ":"
<< main->getType() << std::endl;
}
于 2013-11-06T13:37:50.167 に答える