5

我是 Qt 初学者,需要编写一些数据类。QSharedDataPointer像示例(此处)中那样编写所有这些类是否是一种好方法,或者这是否过多的开销(除了它更多的工作之外)?

我的课在性质上非常像下面的Employee课。我将不得不处理数百个实例,而不是一万或数百万。

我使用 QSharedData / QShareDataPointer 的动机是简化手动内存管理并具有通用代码样式。但我仍然不确定我是否监督了一些警告。

示例

class EmployeeData : public QSharedData
 {
 public:
     EmployeeData();
     EmployeeData(const EmployeeData &other);
     ~EmployeeData();

     int id;
     QString *name;
 };

 class Employee
 {
 public:
     Employee();
     Employee(int id, const QString &name);

     void setId(int id) { d->id = id; }
     void setName(const QString &name);

     int id() const { return d->id; }
     QString name() const;

 private:
     QSharedDataPointer<EmployeeData> d;
 };
4

1 回答 1

5

使用 QSharedDataPointer/pImpl 的优点是:

1) 在某些情况下,您可以避免一些数据复制(例如,如果您有两个或多个相同的 Employee 对象,它们可以共享相同的 EmployeeData 后端,而不是每个都有自己的相同数据的单独副本)

2) 在向 EmployeeData 类添加额外的数据字段后,只需要重新编译 Employee 类的源代码,因为只有 Employee 类(可能)会直接访问 EmployeeData 类。您的所有其他代码将(可能)仅访问 Employee 类,因此不需要重新编译,因为 Employee 类的大小和布局不会改变。

在适当的情况下,这两个原因都可能令人信服——例如,Qt 本身受益于 pImpl 和许多地方的隐式共享,因为 Qt 需要极其有效地处理大量数据,更重要的是因为 Qt 与第三方的关系开发人员要求它保证新的 Qt 共享库版本将保持向后兼容现有的第三方应用程序可执行代码,这些代码是针对旧 Qt 版本编译的。

但是,对于您的个人计划,您不太可能会看到很多好处。如果您的数据对象与 EmployeeData 示例类中显示的一样小/简单(或者即使它们比那个大 10 或 100 倍),那么仅制作数据副本的开销可能会很小......并且因为您大概可以在需要时重新编译自己的代码库,因此向后兼容的好处对您来说并不重要。

所以我的建议是保持简单,只用标准的 C++ 方式做事,在必要时制作成员对象的常规旧默认复制构造函数样式副本(并尽可能通过 const-reference 将对象传递给方法,以最小化它们被复制的次数)。如果您注意到一个可衡量的性能问题,此时您可以返回并使用 pImpl/QSharedDataPointer 重写您的一些类,看看它是否为您提供了可衡量的加速(尽管您可能会发现它不会)。

于 2012-07-16T05:12:23.987 回答