Qt documentation表明使用QSharedDataPointer及其下级的可见实现不典型。
所以根据文档中的小例子,我提出了以下来源(SSCCE)。
接口是直接的,只是私有类和句柄类的前向声明,声明了copy-ctor和d-tor:
#include <QtCore/QSharedDataPointer>
class ModelPrivate;
class Model {
public:
Model();
Model(const Model &other);
~Model();
QSharedDataPointer<ModelPrivate> d;
};
宣布并定义劣等类。
#include <QSharedData>
class ModelPrivate:
public QSharedData {
public:
};
包括从文档中获取的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() {
}
一切都失败了。
#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'
我无法根据文档弄清楚如何按照预期的方式完成这项工作,即也不会在标题中完全声明私有类。我知道这样做有用,但我想了解文档。分配共享类的示例也包含在文档中。来自上面链接的文档:
此处不严格要求复制构造函数,因为类 EmployeeData与Employee类包含在同一文件中 (employee.h)。但是,包括QSharedData的私有子类 在与包含QSharedDataPointer的公共类相同的文件中 不典型。通常,这个想法是隐藏私有子类 来自用户的QSharedData将其放在一个单独的文件中 不包含在公共文件中。在这种情况下,我们通常会 将类EmployeeData放在一个单独的文件中,该文件不包括在内 在employee.h中。相反,我们只是预先声明私有子类 employee.h中的EmployeeData这样:
我认为在分配operator=
时使用的Model
编译失败。
答案 0 :(得分:5)
您的概念有几个主要问题:
您需要将私有类放在单独的文件中,以便与原始想法不同。
无论您是在写这篇文章,都使用了文档中原始示例的概念,但您根本没有。您更改了复制构造函数概念以复制assighment。当然,您需要分别重新实现该运算符。
以下是我对官方示例进行重写的工作示例,因为我认为最好为后代定制,而不是为了更好的理解,为了更好的理解而更好地与上游进行内联:
#include "employee.h"
int main()
{
Employee e1(1001, "Albrecht Durer");
Employee e2 = e1;
Emplyoee e3;
e3 = e2;
e1.setName("Hans Holbein");
}
#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
#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
#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;
}
TEMPLATE = app
TARGET = main
QT = core
HEADERS += employee.h employee_p.h
SOURCES += main.cpp employee.cpp
答案 1 :(得分:0)
问题在于通过d
类中的模板声明和定义的QSharedDataPointer
成员的赋值运算符。
解决方案与将共享类的赋值运算符移动到模块中一样简单:
#include <QtCore/QSharedDataPointer>
class ModelPrivate;
class Model {
public:
Model();
Model(const Model &other);
Model &operator =(const Model &other); /* <-- */
~Model();
QSharedDataPointer<ModelPrivate> d;
};
#include <QSharedData>
class ModelPrivate:
public QSharedData {
public:
};
#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;
}
#include <QString>
#include "Model.h"
int main() {
QString s1, s2;
s2 = s1;
Model m1, m2;
m2 = m1;
}
TEMPLATE = app
TARGET = example
QT = core
HEADERS += Model.h Model_p.h
SOURCES += Model.cc main.cc
这实际上就是Qt宇宙中其他类本身的实现方式。例如,请考虑QTextCursor
。