C++对象工厂函数
可以说我有以下的数据结构:C++对象工厂函数
struct Base
{
Base(const int id, const std::string &name, const std::string &category):
id(id), name(name), category(category) {}
int id;
std::string name;
std::string category;
};
struct A : public Base
{
A(const int id, const std::string &name, const std::string &category,
const int x, const int y) :
Base(id, name, category), x(x), y(y) {}
int x, y;
};
我想创建一个返回派生类,这里的ID,名称和类别的载体的单个工厂方法在函数中是已知的。我遇到的问题是切片...
std::vector< Base* > getVector(...)
struct A的数据成员丢失了! (dynamic_cast的回A可以接受的生产代码?)
所以我有这个模板的方法,但我仍然不认为它的最好的解决办法:
template< class T >
std::vector<T> getVector()
{
std::vector<T> retVal;
retVal.push_back(T(45, "The Matrix", "Science Fiction"));
retVal.push_back(T(45, "Good Luck Chuck", "Comedy"));
...
return retVal;
}
难道还有比模板以外的任何更好的解决方案方法?
你问的似乎值得商榷,因为你想:
- 抽象对象的创建,直到运行时
- 在编译时访问对象的创建后的特定成员
因此,有没办法让它工作得体。你的模板代码仍然需要在调用者站点静态地知道你的对象的类型,所以创建对象不会被抽象出来。
我的建议是再次考虑你的问题:你为什么想要一个动态工厂?为什么不能在Base
类中共享访问器?
如果你不能清楚地回答这两个问题,这可能意味着你不应该有这个类的层次结构。
我其实认为你的模板可能是最好的解决方案,至少它是惯用的C++。
使用RTTI(如dynamic_cast
)也可以,但它不太安全(运行时与编译时类型检查)并且效率通常较低。然而,有时 - 或者经常在的事实 - 你需要有多态性在运行时决定只(例如,当你在同std::vector
需要不同的派生的对象而不能使用固定长度std::tuple
)。然后,您可以像您已经准备好的那样,通过使用基类指针而不是对象的矢量来解决切片问题。与(普通)指针的问题是,他们多少有些回避C++的自动内存管理:当std::vector<Base*>
超出范围,所指向的派生的对象是不按逗留闲逛的地方人迹罕至删除:你有内存泄漏。这就是为什么像Java这样的语言更多依赖于这种继承方式的垃圾收集。 This problem is discussed elsewhere,推荐的解决方案是用std::unique_ptr<Base>
代替Base*
。
一旦你有了这个运行,那么你可以利用运行时多态性的功能。你通常不需要dynamic_cast
,而是应该写到哪不同来源的情况下,不同的虚成员函数的一切。
你的'std :: vector getVector(...)'如何展示切片?你的成员会有不同的派生类型吗? –
2013-02-18 22:39:06
您对问题的描述(“我遇到的问题是切片”)不完整。请发布一个**短**,**完整**程序来展示您的问题。请参阅http://sscce.org/。 – 2013-02-18 22:44:32
“Base *”与“A *”大小相同。指针不会被切分。 – 2013-02-18 22:48:51