C++ 在C+中实现工厂方法的首选方法是什么+;?

C++ 在C+中实现工厂方法的首选方法是什么+;?,c++,memory-management,factory,C++,Memory Management,Factory,一个新手问题:我有一个带有一些虚拟函数的类层次结构,我正在尝试实现一个工厂方法,但我不确定什么是最好的方法: 从工厂方法返回一个原始指针,并将其包装为调用方法中的智能指针 从工厂返回智能指针 从工厂返回一个适当的对象(但它是否要正确复制派生类?),并将其分配给调用方法中的本地对象 从工厂返回引用(但是如何在工厂方法中创建对象而不发生内存泄漏?) 如果能举一个工厂方法和最小客户机的例子,我将不胜感激,它既有效又不会泄漏内存 我的背景是C++和java,所以我在C++ ATM内存管理方面有点迷失了。

一个新手问题:我有一个带有一些虚拟函数的类层次结构,我正在尝试实现一个工厂方法,但我不确定什么是最好的方法:

  • 从工厂方法返回一个原始指针,并将其包装为调用方法中的智能指针
  • 从工厂返回智能指针
  • 从工厂返回一个适当的对象(但它是否要正确复制派生类?),并将其分配给调用方法中的本地对象
  • 从工厂返回引用(但是如何在工厂方法中创建对象而不发生内存泄漏?)
  • 如果能举一个工厂方法和最小客户机的例子,我将不胜感激,它既有效又不会泄漏内存


    我的背景是C++和java,所以我在C++ ATM内存管理方面有点迷失了。

    < p>选项3和4从一开始就不存在了,因为它们根本不起作用:3个对象,4个内存泄漏或无效的引用。 从其他两种方法中,我强烈建议使用2:返回智能指针。事实上,尽可能避免使用原始指针。不幸的是,C++使这篇文章写得很多(这不是一个小的反对意见!任何曾经在C++中编写过面向对象代码的人,并且使用智能指针损坏了我的痛苦),但是另一种选择则更痛苦。
    当然,还有第五种选择:使用原始指针和垃圾收集器。

    我喜欢返回智能指针。是指向返回智能指针的示例抽象工厂的链接


    my2c

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

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

    智能指针的主要问题是缺少协方差,这是实现
    克隆
    虚拟方法时的痛苦。不幸的是,协方差规则在C++0x中没有放松,因此它仍然是一个问题

    另一方面,返回一个原始指针并将其留给调用者来完成,这为bug打开了大门(尽管这是Boost为其克隆选择的方法)

    我个人建议:

    • 臭名昭著的
      auto_ptr
      或调用方应该用C++03包装的普通指针
    • 一旦编译器得到一个
      唯一的\u ptr

    后者结合了大多数优点(不考虑协方差),并且几乎不包含性能开销。

    在使用方法1之后,我可以向您保证,方法2要么返回
    boost::shared_ptr
    要么返回
    boost::scoped_ptr
    (如果您没有访问
    std::unique\u ptr
    的权限,通常前者是您想要的)这是我衷心建议的。

    @ThomasMcLeod:使用
    auto\u ptr
    几乎没有开销,一旦C++0x启动了
    唯一的
    。@Matt:可能很少,但不是零。@ThomasMcLeod:我确实维护零。典型的实现,
    auto\u ptr
    只是一个指针。它的析构函数调用需要一个check…除非编译器可以证明它是不必要的(例如:您访问对象,那么这意味着指针是非空的,否则您调用了未定义的行为)。因此,析构函数实际上是一个删除调用,您无论如何都会执行。哦,我显然忘记了NRVO,所以在这个过程中没有涉及任何副本。记住,我不知道是否有编译器是“邪恶的”足以根据用户访问假设非空指针,但这是允许的。@马特:至少有引用计数init。@ThomasMcLoed:否!在
    自动\u ptr
    作用域\u ptr
    唯一\u ptr
    中没有引用计数:资源的唯一所有者可以转移(除了
    scoped_ptr
    )但仅此而已。并非所有智能指针都是相似的!一致返回
    boost::shared_ptr
    实际上通常是一个好主意。这并不是一个很大的痛苦(至少比原始指针痛苦小得多)。因为大多数多态层次结构都是由不可复制的对象组成的(即,不提供克隆方法的)共享语义通常是您想要的。但要注意循环依赖。@Alexandre:根据我的经验,循环依赖非常非常罕见。至少在您不使用事件/信号的情况下是如此。并且存在弱引用(即公共指针)老实说,这可能是最好的解决方案。不知道,在C++中从来没有这样做过。老实说,它们很少见。但是当他们开机时,你就遇到了麻烦。弱指针应该能解决这个问题,但是你永远不知道在循环引用的存在下,什么样的设计是弱的。所以这是一个潜在的重大问题。我更喜欢使用UnQuyGPTR,因为它更多。强烈强制所有权。@null同意。这个答案早于C++11的广泛可用性,否则它会使这个偏好非常明确。