正在寻找一种应用于C++; 我有如下C++类定义: A类 { 公众: B*createB(); }; B类 { 公众: 虚拟void fun()=0; }; B1类:B{/*…*/}; B2类:B{/*…*/};

正在寻找一种应用于C++; 我有如下C++类定义: A类 { 公众: B*createB(); }; B类 { 公众: 虚拟void fun()=0; }; B1类:B{/*…*/}; B2类:B{/*…*/};,c++,oop,design-patterns,C++,Oop,Design Patterns,基本上,B是一个抽象类,B1和B2是B的具体实现,A在代码中的某个地方创建了一个B类型的实例。需要注意的是,A不是工厂,A::createB只是一个例子 我希望能够在a的初始化过程中传递B的子类,以便后者在运行时根据需要创建前者的实例。例如: A *a1 = /* sorcery here */; A *a2 = /* another magic code */; a1->createB(); // getting B1 a2->createB(); // getting B2

基本上,B是一个抽象类,B1和B2是B的具体实现,A在代码中的某个地方创建了一个B类型的实例。需要注意的是,A不是工厂,
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"
B类
{
公众:
虚拟void fun()=0;
虚拟B*克隆()=0;
};
B1类:公共B类
{
公众:
虚拟虚空乐趣()
{
std::cout fun();//打印“B1”
A(新的B2()).createB()->fun();//打印“B2”
在B中实现
clone()
方法

创建时将a
B*
传递给a。a将调用B的
clone()
,并将该
B*
作为参数

有关克隆的更多信息,请参见问题和其他。

您可以使用设计模式来实现这一点。将
A
传递给
B1
B2
,并将
clone()
成员函数添加到
B
,如下所示:

class B 
{
public:
    virtual void fun() = 0;
    virtual B* clone() = 0; // B1::clone returns new B1; B2::clone returns new B2
};
A
存储初始化过程中传入的
B
的原型实例供以后使用。当它需要创建新的
B
时,它会调用原型上的
clone()
,以获得正确类的实例。

听起来像是您想要的

您可以看到以下示例:

#包括
#包括
类窗口
{
受保护的:
整数宽度;
内部高度;
字符串工具包;
std::字符串类型;
窗口(std::string usedToolkit,std::string windowType)
:toolkit(usedToolkit),类型(windowType)
{}
公众:
std::string getToolkit()
{
返回工具包;
}
std::string getType()
{
返回类型;
}
};
GtkToolboxWindow类:公共窗口
{
公众:
GtkToolboxWindow()
:窗口(“Gtk”、“工具箱窗口”)
{}
};
GtkLayersWindow类:公共窗口
{
公众:
GtkLayersWindow()
:窗口(“Gtk”、“图层窗口”)
{}
};
类GTK主窗口:公共窗口
{
公众:
GtkMainWindow()
:窗口(“Gtk”、“主窗口”)
{}
};
类QtToolboxWindow:公共窗口
{
公众:
QtToolboxWindow()
:窗口(“Qt”、“ToolboxWindow”)
{}
};
类QtLayersWindow:公共窗口
{
公众:
QtLayersWindow()
:窗口(“Qt”、“层窗口”)
{}
};
类QtMainWindow:公共窗口
{
公众:
QtMainWindow()
:窗口(“Qt”、“主窗口”)
{}
};
/*这是抽象工厂*/
二级工厂
{
公众:
虚拟窗口*getToolboxWindow()=0;
虚拟窗口*getLayersWindow()=0;
虚拟窗口*getMainWindow()=0;
};
/*Gtk工具包工厂*/
GTKU类工厂:公用工厂
{
公众:
Window*getToolboxWindow()
{
返回新的GtkToolboxWindow();
}
窗口*getLayersWindow()
{
返回新的GtkLayersWindow();
}
Window*getMainWindow()
{
返回新的GtkMainWindow();
}
};
/*Qt工具包工厂*/
QtUIFactory类:公共UIFactory
{
公众:
Window*getToolboxWindow()
{
返回新的QtToolboxWindow();
}
窗口*getLayersWindow()
{
返回新的QtLayersWindow();
}
Window*getMainWindow()
{
返回新的QtMainWindow();
}
};
int main()
{
ui工厂*ui=0;
/*检查正在运行的环境
并创建合适的工厂*/
如果(/*Gtk==*/true)
{
ui=新的GtkUIFactory();
}
其他的
{
ui=新的QtUIFactory();
}
/*使用工厂来构建接口*/
Window*toolbox=ui->getToolboxWindow();
Window*layers=ui->getLayersWindow();
Window*main=ui->getMainWindow();
/*看看我们得到了什么*/
std::cout getToolkit()
#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;
}