带有前向声明类的 QSharedDataPointer
QSharedDataPointer with forward-declared class
Qt文档表明,使用QSharedDataPointer 及其劣质的可见实现并不典型。
因此,根据文档中截取的小示例,我想出了以下来源(SSCCE)。
界面:模型.h
接口很简单,只是私有类和句柄类的前向声明,声明了 copy-ctor 和 d-tor:
#include <QtCore/QSharedDataPointer>
class ModelPrivate;
class Model {
public:
Model();
Model(const Model &other);
~Model();
QSharedDataPointer<ModelPrivate> d;
};
专用标头:Model_p.h
只是声明和定义下级类。
#include <QSharedData>
class ModelPrivate:
public QSharedData {
public:
};
实施:Model.cc
包括 c-tors/d-tor 的实现,取自文档。
#include "Model.h"
#include "Model_p.h"
class ModelPrivate:
public QSharedData {
};
Model::Model():
d(new ModelPrivate()) {
}
Model::Model(const Model &other):
d(other.d) {
}
Model::~Model() {
}
用例:main.cc
一切都失败了。
#include <QString>
#include "Model.h"
int main(int argc, char *argv[]) {
QString s1, s2;
s2 = s1;
Model m1, m2;
m2 = m1;
}
只有两个实例和一个赋值,就像任何其他共享类一样。但是,由于以下原因,它失败得很严重
invalid use of incomplete type 'class ModelPrivate'
我无法弄清楚如何根据文档以预期的方式使其工作,即没有在标头中完全声明私有类。我知道这样做时它有效,但我想了解文档。分配共享类的示例也包含在文档中。从上面链接的文档:
这里并不严格要求复制构造函数,因为类 员工数据包含在与类员工相同的文件中 但是,包括 QSharedData 的私有子类。 与包含 QSharedDataPointer 的公共类位于同一文件中 不典型。通常,这个想法是隐藏私有子类 QShared数据从用户,将其放在一个单独的文件中,这将 不包含在公共文件中。在这种情况下,我们通常会 将类 EmployeeData 放在一个单独的文件中,该文件将不包含在内 在员工中。相反,我们只是预先声明私有子类 员工数据在 employee.h 中是这样:
我想编译在分配Model
时使用的operator=
失败.
您的概念有几个主要问题:
- 您
确实需要将私有类放在单独的文件中才能做到这一点,这与您最初的想法不同。
无论您是否在编写是否使用了文档中原始示例的概念,您都没有。您将复制构造函数概念更改为复制辅助。当然,您需要分别重新实现该运算符。
这是我为官方示例重写的工作示例,因为我认为为后代自定义它比您的发散示例更好,以便与上游更一致以便更好地理解:
主.cpp
#include "employee.h"
int main()
{
Employee e1(1001, "Albrecht Durer");
Employee e2 = e1;
Emplyoee e3;
e3 = e2;
e1.setName("Hans Holbein");
}
员工.h
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include <QSharedDataPointer>
#include <QString>
class EmployeeData;
class Employee
{
public:
Employee();
Employee(int id, QString name);
Employee(const Employee &other);
Employee& operator =(const Employee &other);
~Employee();
void setId(int id);
void setName(QString name);
int id() const;
QString name() const;
private:
QSharedDataPointer<EmployeeData> d;
};
#endif
employee_p.h
#ifndef EMPLOYEE_P_H
#define EMPLOYEE_P_H
#include <QSharedData>
#include <QString>
class EmployeeData : public QSharedData
{
public:
EmployeeData() : id(-1) { }
EmployeeData(const EmployeeData &other)
: QSharedData(other), id(other.id), name(other.name) { }
~EmployeeData() { }
int id;
QString name;
};
#endif
员工.cpp
#include "employee.h"
#include "employee_p.h"
Employee::Employee()
{
d = new EmployeeData;
}
Employee::Employee(int id, QString name)
{
d = new EmployeeData;
setId(id);
setName(name);
}
Employee::Employee(const Employee &other)
: d (other.d)
{
}
Employee& Employee::operator =(const Employee &other)
{
d = other.d;
return *this;
}
Employee::~Employee()
{
}
void Employee::setId(int id)
{
d->id = id;
}
void Employee::setName(QString name)
{
d->name = name;
}
int Employee::id() const
{
return d->id;
}
QString Employee::name() const
{
return d->name;
}
main.pro
TEMPLATE = app
TARGET = main
QT = core
HEADERS += employee.h employee_p.h
SOURCES += main.cpp employee.cpp
问题实际上在于通过 QSharedDataPointer
类中的模板声明和定义的 d
成员的赋值运算符。
该解决方案就像将共享类的赋值运算符移动到模块中一样简单:
新界面:模型.h
#include <QtCore/QSharedDataPointer>
class ModelPrivate;
class Model {
public:
Model();
Model(const Model &other);
Model &operator =(const Model &other); /* <-- */
~Model();
QSharedDataPointer<ModelPrivate> d;
};
专用标头:Model_p.h
#include <QSharedData>
class ModelPrivate:
public QSharedData {
public:
};
实现: Model.cc:
#include "Model.h"
#include "Model_p.h"
Model::Model():
d(new ModelPrivate()) {
}
Model::Model(const Model &other):
d(other.d) {
}
Model::~Model() {
}
Model &Model::operator =(const Model &other) {
d = other.d;
return *this;
}
用例:main.cc
#include <QString>
#include "Model.h"
int main() {
QString s1, s2;
s2 = s1;
Model m1, m2;
m2 = m1;
}
项目文件:example.pro
TEMPLATE = app
TARGET = example
QT = core
HEADERS += Model.h Model_p.h
SOURCES += Model.cc main.cc
事实上,这就是Qt宇宙本身中其他类的实现方式。例如,考虑QTextCursor
.
- 没有找到相关文章