2011-01-24 74 views
12

一个新手的问​​题:我有个教学班,一些虚拟功能的层次,我想实现一个工厂方法,但我不知道什么是最好的方法:在C++中实现工厂方法的首选方法是什么?

  1. 返回原始指针从工厂方法并将其包装到调用方法中的智能指针中
  2. 返回工厂的智能指针
  3. 从工厂返回一个正确的对象(但它是否正确复制派生类?)并将其分配给调用方法中的本地对象
  4. 返回工厂的引用(但是如何创建在工厂方法中的对象没有内存泄漏?)

我将不胜感激的工厂方法和最小的客户端,这是有效的,不泄漏内存的例子。

我的背景是C#和Java,所以我有点在C++ atm中的内存管理中丢失了。

回答

8

选项3和选项4从一开始就没有了,因为它们根本不起作用:3个对象片,4个创建内存泄漏或无效引用。

从其他两种方法中,我强烈推荐2:返回一个智能指针。事实上,如果可能的话,尽量避免使用原始指针。不幸的是,C++使得写这么多东西成为可能(而且这不是一个微不足道的反对!任何曾经用C++写过面向对象的代码,并且使用智能指针的人都感到痛苦),但是替代方案更加痛苦。

当然,替代方案5:使用原始指针和垃圾回收器。

+0

实际上,持续返回`boost :: shared_ptr`通常是一个好主意。这不是一个很大的痛苦(至少比原始指针更痛苦)。由于大多数多态层次结构是由不可复制的对象组成的(即不提供`clone`方法),共享语义往往是你想要的。虽然谨防循环依赖。 – 2011-01-24 18:34:33

+1

@Alexandre:根据我的经验,循环依赖是真的,非常罕见。至少当你不使用事件/信号时。那些弱引用(即普通指针)可能始终是最好的解决方案。不知道。说实话,从来没有用C++做过。 – 2011-01-24 18:55:07

4

好我的口味去返回一个智能指针。 here是指向返回智能指针的示例抽象工厂的链接。

my2c

3

我更喜欢方法1,因为它更灵活。但是,返回原始指针还是智能指针实际上只是对象使用的问题。例如,您可能想要返回一个原始指针,因为您知道该对象有时会被使用一次,并立即在相同的代码块中被删除。在这种情况下,不需要承担构建智能指针对象的开销。但是,如果对象的生命周期总是不确定,并且担心内存泄漏,那么通过所有方法都可以使用方法2.方法3和4不正确。

1

您需要内存管理,没有其他可行的选择。但是,您可能不需要工厂方法中的内存管理。

智能指针的主要问题是缺少协方差,这在实现clone虚拟方法时很痛苦。不幸的是协变规则在C++ 0x中没有放宽,所以它仍然是一个问题。另一方面,返回一个原始指针并将其留给调用者来包装它,正在打开bug的大门(尽管它是Boost为它的克隆选择的方法)。

就个人而言,我建议:

  • 臭名昭著auto_ptr或一个普通的指针调用者应在包装C++ 03
  • 一个unique_ptr只要你的编译器得到它

后者结合了大多数优点(抛开协方差),并且几乎没有性能开销。

0

与方法1已经挣扎后,我可以向你保证,方法2,要么返回boost::shared_ptrboost::scoped_ptr(通常前者是你想要什么,如果你没有std::unique_ptr访问)是什么,我全心全意支持建议。

相关问题