我所做的是从基础brokeredobject类派生所有对象:
class brokeredobject { virtual int GetInterfaceId() = 0; };
然后我有一个Objectbroker“工厂”.当有人需要一个对象时,请调用GetobjectByID(). boker在STL列表中查看该对象是否已存在,如果存在,则返回该对象.如果没有,它会创建它,将其放入列表并返回它.一切都很好.
brokeredobject *GetobjectByID(int id) { brokeredobject *pObject; ObjectMap::iterator = m_objectList.find(id); // etc. if(found) return pObject; // not found,so create switch(id) { case 0: pObject = new TypeA; break; case 1: pObject = new TypeB; break; // etc. // I loathe this list } // add it to the list return pObject; }
我觉得痛苦的是维护这个ID列表并让每个类实现它.我至少让我的消费者的生活变得更容易了,让每个类型都拥有关于它自己的ID的信息,如下所示:
class TypeA : public brokeredobject { static int get_InterfaceID() { return IID_TYPEA; } int GetInterfaceID() { return get_InterfaceID(); } };
所以我可以得到一个像这样的对象:
GetobjectByID(TypeA::get_InterfaceID());
有必要实际知道ID映射是什么,但我仍然对维护和错误的可能性感到不满.似乎如果我知道类型,为什么我还要知道ID?
我渴望的是C#中的这样的东西:
brokeredobject GetorCreateObject<T>() where T : brokeredobject { return new T(); }
Objectbroker将根据传入的类型创建对象.
C#已经破坏了我,这只是生活中的一个事实,C不能做到这一点,或者有没有办法实现这一点,我没有看到?
解决方法
template<typename T> brokeredobject * GetorCreateObject() { return new T(); }
这将与C#代码一样工作和执行.它也是类型安全的:如果你传递的类型不是从brokeredobject继承的(或者不是那个类型本身),那么编译器会在return语句中发出声音.但是它总是会返回一个新对象.
独生子
正如另一个人建议的那样(相信他),这一切看起来非常像单身人士模式的优秀案例.只需执行TypeA :: getInstance()即可获得存储在该类的静态变量中的单个实例和单个实例.我想这将比上述方法容易得多,而不需要ID来解决它(我之前展示了一种使用模板在这个答案中存储ID的方法,但我发现它实际上只是单身人士).
我已经读过你将有机会打开多个类的实例.一种方法是拥有一个Mingleton(我编造了这个词:))
enum MingletonKind { SINGLetoN,MULTITON }; // Singleton template<typename D,MingletonKind> struct Mingleton { static boost::shared_ptr<D> getorCreate() { static D d; return boost::shared_ptr<D>(&d,NoopDel()); } struct NoopDel { void operator()(D const*) const { /* do nothing */ } }; }; // Multiton template<typename D> struct Mingleton<D,MULTITON> { static boost::shared_ptr<D> getorCreate() { return boost::shared_ptr<D>(new D); } }; class ImASingle : public Mingleton<ImASingle,SINGLetoN> { public: void testCall() { } // Indeed,we have to have a private constructor to prevent // others to create instances of us. private: ImASingle() { /* ... */ } friend class Mingleton<ImASingle,SINGLetoN>; }; class ImAMulti : public Mingleton<ImAMulti,MULTITON> { public: void testCall() { } // ... }; int main() { // both do what we expect. ImAMulti::getorCreate()->testCall(); ImASingle::getorCreate()->testCall(); }
现在,您只需使用SomeClass :: getorCreate(),它就会关注细节.对于shared_ptr,单例情况下的自定义删除操作使删除成为无操作,因为shared_ptr拥有的对象是静态分配的.但是,请注意静态变量的破坏顺序问题:Static initialization order fiasco
原文地址:https://www.jb51.cc/c/116714.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。