簡體   English   中英

具有預先聲明的類的QSharedDataPointer

[英]QSharedDataPointer with forward-declared class

Qt文檔建議將QSharedDataPointer與劣質的可見實現結合使用並不常見

因此,根據文檔中的一個小示例,我提出了以下來源(SSCCE)。

接口:Model.h

該接口很簡單,只是私有類和handle類的前向聲明,其中聲明了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'

我無法根據文檔確定如何使這項工作按預期的方式進行,即也沒有在標頭中完全聲明私有類。 我知道這樣做是可行的,但我想了解這些文檔。 文檔中也包含分配共享類的示例。 從上面鏈接的文檔中:

這里不是嚴格要求復制構造函數,因為EmployeeData類與Employee(employee.h)類包含在同一文件中。 但是,通常不將QSharedData的私有子類與包含QSharedDataPointer的公共類包含在同一文件中。 通常,這種想法是通過將QSharedData的私有子類放置在單獨的文件中來向用戶隱藏,該文件不會包含在公共文件中。 在這種情況下,我們通常將EmployeeData類放在單獨的文件中,該文件不會包含在employee.h中。 取而代之的是,我們只需要在employee.h中預先聲明私有子類EmployeeData:

我想編譯在分配Model時使用的operator=處失敗。

您的概念存在幾個主要問題:

  • 與原始想法不同,您確實需要在單獨的文件中擁有私有類才能做到這一點。

  • 不管您使用的是文檔中原始示例的概念,還是沒有使用。 您將復制構造函數概念更改為復制約束。 自然,您需要分別重新實現該運算符。

這是我為官方示例重寫的工作示例,因為我認為最好為后代自定義該示例,而不是與分散的示例更內聯以更好地理解上游:

main.cpp

#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

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

員工

#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成員的賦值運算符。

該解決方案很簡單,就像將共享類的賦值運算符移動到模塊中一樣:

新接口:Model.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 Universe本身中其他類的實現方式。 例如,考慮QTextCursor

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM