有相当多的事情尚不清楚对你的设计,但如果问题是,是否可以强制执行的类型 T
在件的功能templa Add
可以强制执行从 BaseClass
, ,选择很简单:
- 什么都不做,编译器会很乐意的抱怨就行
BaseClass* baseClass = new T();
- 添加一个静态的主张,使这种更明显的
- 用花式SFINAE技巧,以去除功能设置的超载
我会去任何一个第一二。静态的主张可能是拼写为:
static_assert(std::is_base_of<BaseClass,T>::value);
该SFINAE伎俩,我真避免,因为它将使代码的更多混淆,但可以实现为:
template <class T>
typename std::enable_if<std::is_base_of<BaseClass,T>::value,T*>::type
Add() {
baseClasses.push_back(new T());
return baseClasses.back();
}
(注意,我改变了回返类型 T*
, ,对象是 T
, 为什么一回 BaseClass*
?这同样适用于 Get
功能没有点在返回 BaseClass*
, 当你知道的对象真的是一个 T
)
现在的实际问题是复杂得多,因为你的设计是积极避免考虑的所有权,这你不应该。想想所有权的对象,并确保有一个明确的拥有者(或者说,资源是共享)。一旦你知道谁拥有对象、创建一个协议对其余的代码通知的所有者当一个对象需要予以删除。如果你允许 任何 代码以删除的指针,你会遇到不确定的行为很快。
其他较小的问题可以包括事实上,你正在实施的所有组成部分有一个默认的构造,这可能会或不适当的。你可以简化这种限制具有非模板 Add
需要指针,并让的呼叫者创建的对象的方式,请他们。
使用 typeid
通常的代码-闻闻我不认为这是例外,也许你会更好通过设计类型分层结构中,你可以问的对象是什么,而不是运行 typeid
.如果你真的确定作出的界面,基于类型,然后再考虑是否 dynamic_cast
可能会更好。它将更innefficient,但是如果你有多个级别的继承,它会让你回来的大多数派生的对象为中间体的对象