涉及多态性和资源管理的程序设计
Program design concerning polymorphism & resource management
我有一个叫 Widget
的 class。这个 class 是抽象的并且有虚方法。为了避免对象切片,所有 Widgets
都存储为引用或指针。我有几个带有构造函数的 classes,这些构造函数在内部存储给它们的小部件;因此存储的 Widget
必须在构造函数之外初始化并且不能在对象被销毁之前被销毁,因此通常 Widget
是通过动态内存分配的。我的问题是关于如何处理这个动态内存;我已经整理了一个选项列表(请随意建议其他人。)哪个是最地道的?
1.智能指针。 智能指针似乎是正确的选择,但由于我使用的是 C++98,所以我必须自己编写。我也觉得一直写smart_pointer<Widget>
有点丑
2。存储时复制 Widgets
。 另一种做法是存储传入的副本 Widget
而不是原始文件。这可能会导致对象切片,但我不确定。此外,用户可能想自己编写 classes 来存储传入的 Widgets
,我不想让它太复杂。
3。让用户处理所有事情。 我也许可以让用户确保 Widget
被及时删除。这似乎是 Qt 所做的(?)。然而,这再次使用户的事情复杂化。
我个人比较喜欢这种方式(不一定适用,但我多次成功使用):
class WidgetOwner
{
vector<Widget*> m_data;
public:
RegisterWidget(Widget *p) { m_data.push_back(p); }
~WidgetOwner() { for (auto &p : m_data) delete p; }
};
这个简单的 class 只是存储指针。这个 class 可以存储 Widget
的任何衍生物,前提是 Widget
具有虚拟析构函数。对于多态 class 这应该不是问题。
注意Widget一旦注册,就不能销毁,除非全部销毁。
这种方法的优点是可以自由传递指针。它们都将有效,直到存储被销毁。这是一种手工制作的游泳池。
我认为智能指针是最好的选择。如果你觉得模板很难看,试试typedef
Which is the most idiomatic?
最惯用的肯定是下一个版本的 c++ 决定的 "the way to go",那就是 智能指针(您可以 find/use例如,在 boost 上实现,互联网上的其他实现可能更容易获得灵感)。
您还可以决定,由于您使用的是 c++98
(这是一个需要考虑的重要因素),因此您可以采用该上下文的惯用语,并且由于那几乎是无人区,所以答案最有可能是最吸引您的自制设计。
我有一个叫 Widget
的 class。这个 class 是抽象的并且有虚方法。为了避免对象切片,所有 Widgets
都存储为引用或指针。我有几个带有构造函数的 classes,这些构造函数在内部存储给它们的小部件;因此存储的 Widget
必须在构造函数之外初始化并且不能在对象被销毁之前被销毁,因此通常 Widget
是通过动态内存分配的。我的问题是关于如何处理这个动态内存;我已经整理了一个选项列表(请随意建议其他人。)哪个是最地道的?
1.智能指针。 智能指针似乎是正确的选择,但由于我使用的是 C++98,所以我必须自己编写。我也觉得一直写smart_pointer<Widget>
有点丑
2。存储时复制 Widgets
。 另一种做法是存储传入的副本 Widget
而不是原始文件。这可能会导致对象切片,但我不确定。此外,用户可能想自己编写 classes 来存储传入的 Widgets
,我不想让它太复杂。
3。让用户处理所有事情。 我也许可以让用户确保 Widget
被及时删除。这似乎是 Qt 所做的(?)。然而,这再次使用户的事情复杂化。
我个人比较喜欢这种方式(不一定适用,但我多次成功使用):
class WidgetOwner
{
vector<Widget*> m_data;
public:
RegisterWidget(Widget *p) { m_data.push_back(p); }
~WidgetOwner() { for (auto &p : m_data) delete p; }
};
这个简单的 class 只是存储指针。这个 class 可以存储 Widget
的任何衍生物,前提是 Widget
具有虚拟析构函数。对于多态 class 这应该不是问题。
注意Widget一旦注册,就不能销毁,除非全部销毁。
这种方法的优点是可以自由传递指针。它们都将有效,直到存储被销毁。这是一种手工制作的游泳池。
我认为智能指针是最好的选择。如果你觉得模板很难看,试试typedef
Which is the most idiomatic?
最惯用的肯定是下一个版本的 c++ 决定的 "the way to go",那就是 智能指针(您可以 find/use例如,在 boost 上实现,互联网上的其他实现可能更容易获得灵感)。
您还可以决定,由于您使用的是 c++98
(这是一个需要考虑的重要因素),因此您可以采用该上下文的惯用语,并且由于那几乎是无人区,所以答案最有可能是最吸引您的自制设计。