C++抽象工厂是否应该为构造对象提供销毁方法
Should C++ abstract factory provide destroy method for constructed objects?
考虑以下接口(使用哑指针,因为我们仍在C++98(
class WidgetMaker {
virtual Widget* makeWidget() = 0;
};
通过以下可能的实现
class SpecificWidgetMaker: public WidgetMaker {
Widget* makeWidget() {
return new SpecificWidget();
}
};
Widget 是一些带有虚拟析构函数的基类,SpecificWidget 扩展了它。我的同事声称WidgetMaker界面应该包含以下方法
virtual void freeWidget(Widget* widget);
理由是,这样我们就不会强制 makeWidget 实现使用标准的新分配,它们可以使用自定义池分配器,或者在 widget 无状态或其他情况下始终返回相同的全局实例。
我觉得这样的设计通常是一个坏主意 - 它使客户端代码复杂化,违反了KISS和YAGNI,使过渡(在未来20年内在我们的组织中不太可能(变得更加困难unique_ptr。我应该相信自己的感觉吗?在什么情况下,自由方法作为抽象工厂接口的一部分是合理的?
你朋友提出的解决方案(实际上,也是你原来的解决方案(的一个问题是它有一个不必要的非平凡协议。一旦你通过 makeWidget
获得一个Widget
,你需要记住解除分配它(直接,或者通过调用工厂的某个方法(。众所周知,这是脆弱的 - 它要么会迅速崩溃(导致Widget
泄漏(,要么会使客户端代码真正复杂化。
如果你看一下std::shared_ptr::shared_ptr(...)
的界面,你可以看到它可以接受一个自定义的删除器对象。
因此,也许你可以typedef
(或等效的(什么是Widget
智能指针:
using WidgetPtr = std::shared_ptr<Widget, ...>
如果您以后决定工厂需要在解除分配Widget
时执行某些操作,则可以将typedef
更改为使用自定义删除程序的,此自定义删除程序可以通知工厂正在删除对象。
这样做的主要优点是它消除了记住从用户那里解除分配Widget
的责任。
说这里没有一般的经验法则。这完全取决于您Widget
实施的细节。
如果正确销毁任何Widget
子类的实例所需的所有操作都可以在其普通析构函数中处理,则在因子中声明显式freeWidget
(( 没有任何用处。它不会增加任何价值。
另一方面,如果需要在析构函数中执行由于某种原因无法处理的事情,那么显然,您需要一个显式方法来销毁您的小部件。
也许目前不需要任何特殊处理,这种处理,但你预见到将来需要它。在这种情况下,声明显式 freeWidget
(( 方法是有意义的,以避免以后重写一堆代码。
如果您决定采用 freeWidget
(( 方法,您可以考虑做的一件事是将所有子类的析构函数设为私有(最有可能使用一些合适的friend
声明,以便某些东西实际上可以破坏这些东西(,以强制执行此策略。
您可能希望显式freeWidget
(( 的一个示例是例外。从析构函数中抛出异常是...敏感。这是允许的,但它带有某些...限制。因此,如果销毁小部件可能会引发异常,则在这种情况下,使用 freeWidget
(( 将允许您更好地控制引发异常,并在执行此操作之前正确清理已销毁的小部件。
- 使用std::函数映射对象方法
- 正在调用shared_ptr对象方法
- 检查哪个对象调用了另一个对象的对象方法
- 如何在C++中循环访问未知对象方法?
- c++ 替换调用对象方法的宏函数
- 我能否通过将函数实现为类对象方法来避免使用互斥锁
- 我可以制作一个对象方法,如果单独调用,它将自行修改,但如果在复制初始化期间调用,则会返回一个新对象?
- 如何让两个不同的对象方法相互用作参数
- 在创建 c++ 期间调用对象方法
- 扩展中的日期时间对象方法C++问题
- 将对象方法从向量应用于C 的第二个向量中的对象
- 将 C++/CLI 对象指针传递给本机对象方法
- 多态性的面向对象方法
- 将对象方法传递到变量
- C :使用Main中定义的对象方法的函数
- 有关使用矢量迭代器访问对象方法的问题
- 定义可以执行对象方法和独立函数的函数时出现问题
- 调用列表中子对象方法的最佳方法
- main.cpp:(.text+0x8f):对[对象方法]的未定义引用
- cpp 从需要超类对象的函数访问子类对象方法