【问题标题】:Return a statically or dynamically allocated object from a factory? [duplicate]从工厂返回静态或动态分配的对象? [复制]
【发布时间】:2014-12-10 20:52:38
【问题描述】:

基本上是这样的:

Cat CatFactory::CreateCat()
{
    return Cat();
}

或者这个:

Cat* CatFactory::CreateCat()
{
    return new Cat();
}

我知道一般建议是尽可能避免使用 new,并且倾向于在堆栈上创建对象,这样就不必使用 delete。这也适用于工厂吗?我看到的所有示例都倾向于使用 new 关键字。为什么会这样?

我不能使用智能指针,因为这是一个类项目,每个人都是 C++ 新手,我们必须稍后集成我们的项目。

【问题讨论】:

  • 返回猫();返回一个本地对象,一旦超出范围就会导致使用它时未定义的行为:)您按值返回,因此您在调用代码处再次获得本地副本,但我不推荐它..
  • @cageman 这一点都不正确。 return Cat(); 将按值返回,调用 copy-ctor(由于RVO,即使这样也很有可能会被忽略)。第一个样本中没有 UB。
  • 你的正确,感谢提醒。

标签: c++ memory memory-management new-operator factory


【解决方案1】:

我看到的所有示例都倾向于使用 new 关键字。为什么会这样?

因为工厂模式通常用于避免将构造函数和类层次结构(许多系统中的实现细节!)的知识泄露给调用者;如果您要返回Cat 的子类的实例而不是Cat,您想使用它:

Cat *make_cat(int type)
{
    switch (type) {
        case TABBY:
            return new Tabby();
        case TORTOISESHELL:
            return new Tortoiseshell();
        // etc.
    }
};

如果按值返回,则不能这样做。

按值返回的其他原因包括不可复制的对象。如果你不喜欢使用原始指针,而现代 C++ 风格有它,你应该返回 unique_ptrshared_ptr

【讨论】:

  • 还有一个原因是内存管理。工厂通常是库接口的一部分,用于实现COM style接口。
【解决方案2】:

这完全取决于您在应用程序上下文中所说的“对象”(抽象意义上)是什么意思,以及如何识别它,以及多态性必须对它所起的作用。

如果您的对象不需要是多态的,并且您可以按值识别它们,您可以按值传递它们(或“移动”它们,在 C++11 中)所以 - 事实上 - 你可以使用 "价值语义学”。 在这种情况下,两个都包含“abc”的变量是“相等的”,并被认为在不同的地方(范围)表示“相同的事物”。

如果您通过对象在内存中的位置(也称为地址)来识别对象,那么您必须传递指针或引用,这样就不会进行复制。在这种情况下,两个都包含“abc”的不同变量被认为“代表不同的事物,顺便说一下看起来是一样的”。

如果需要多态性,那么,通过指针(或通过引用,但不是通过值)传递是必须的,因为 C++ 多态性是通过间接方式操作的。

基于 OOP 的程序倾向于遵循第二范式。 函数式或通用程序往往遵循第一个。

这里的重点是,“工厂模式”是一种 OOP 技术,在 OOP 世界之外没有那么有趣。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-13
    • 2011-10-10
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多