Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 继承类的Qt访问D指针_C++_Qt_D Pointer - Fatal编程技术网

C++ 继承类的Qt访问D指针

C++ 继承类的Qt访问D指针,c++,qt,d-pointer,C++,Qt,D Pointer,我正在努力理解我的整个d指针是如何工作的。我得到了大部分零件,但我目前面临一个问题: 像这里的那个家伙一样,我想使用d指针继承一个类(实际上是QProcess) 由于访问d指针的函数是私有的,我不能用简单的继承来访问它。我的想法是再次使用Q_DECLARE_PRIVATE宏来获取函数并访问它。这行吗?在我尝试之前,我想要一些提示,因为我不知道这是否可行 (我需要这个来避免整个许可问题。) MyProcess.h #ifndef MYPROCESS_H #define MYPROCESS_H c

我正在努力理解我的整个d指针是如何工作的。我得到了大部分零件,但我目前面临一个问题:

像这里的那个家伙一样,我想使用d指针继承一个类(实际上是QProcess)

由于访问d指针的函数是私有的,我不能用简单的继承来访问它。我的想法是再次使用Q_DECLARE_PRIVATE宏来获取函数并访问它。这行吗?在我尝试之前,我想要一些提示,因为我不知道这是否可行

(我需要这个来避免整个许可问题。)

MyProcess.h

#ifndef MYPROCESS_H
#define MYPROCESS_H

class QProcessPrivate;

class MyProcess : public QProcess {
   public:
     MyProcess(QObject *parent = 0);

   protected:
     Q_DECLARE_PRIVATE(QProcessPrivate);

};

#endif /* WIDGET_H */
MyProcess.cpp

#include "myprocess.h"

MyProcess::MyProcess(QObject *parent = 0)
      : QProcess(parent) {
}

MyProcess::setPid(Q_PID pid) {
    Q_D(const QProcess);
    d->pid = pid;
}

首先,让我们介绍一下基本知识。伊纳尔,但这里是这样的:

我假设您有一个封闭源代码的应用程序,希望根据LGPL条款使用Qt

根据美国法律的某些解释,使您的代码依赖于Qt的私有头使其成为Qt的派生作品,因此您的代码必须根据LGPL(或GPL)条款提供,除非您拥有商业许可证

根据LGPL,您的义务是让您分发应用程序的人能够将应用程序与他们根据您必须提供给他们的源代码编译的Qt版本重新链接。这可能是由操作系统完成的动态链接,也可能是由链接器实用程序完成的静态链接。不管你是否修改了Qt。他们问,你必须给他们Qt源代码,以及你用来构建应用程序中使用的Qt的确切构建脚本

当您依赖于私有头时,不可能有人对您提供的Qt版本进行二进制兼容的更改,并将其与您的代码重新链接,而不会出现问题。私有Qt类可以在不破坏二进制兼容性的情况下进行更改-这就是它们是私有的原因。我自己对LGPL的解释如下:如果我的代码能够成功链接并使用任何与我随应用程序提供的版本二进制兼容的Qt版本,那么它就不是派生代码。当然,这是在Qt bug和我所做的其他更改的范围内,因此,如果有人将此Qt修补到较旧的版本并期望它正常运行,则可能是不可行的

因此,要保持代码源代码的封闭性,您唯一能做的就是在Qt内部修改
QProcess
的*公共接口。任何人都可以使用这个经过修改的Qt版本(您提供的!),对其进行进一步的二进制兼容更改,并使用您的代码重新链接。因此,如果您认为不修改Qt和依赖私有标题会使您的生活更轻松,您就太离谱了

一般来说,您不能从
QXyzPrivate
继承,因为您需要包含Qt的私有头。所以这不是一个好的做法,也没有很好的理由这么做。当您实例化这个类时,您所付出的代价是额外的堆分配,所以我想说,不要担心

您必须启动自己的私有PIMPL类层次结构。请注意,打算从中派生的每个类都必须提供一个引用私有类实例的构造函数

// myprocess.h

class MyProcessPrivate;
class MyProcess : public QProcess {
  Q_DECLARE_PRIVATE(MyProcess) // No semicolon!
public:
  explicit MyProcess(int arg, QObject * parent = 0);
  ~MyProcess();
protected:
  MyProcess(MyProcessPrivate&, int arg, QObject * parent); // Must be present to allow derivation
  const QScopedPointer<MyProcessPrivate> d_ptr; // Only in the base class, must be protected!
}

// myprocess_p.h

class MyProcessPrivate {
  Q_DECLARE_PUBLIC(MyProcess) // No semicolon!
  ...
public:
  explicit MyProcessPrivate(MyProcess*);
protected:
  MyProcess * const q_ptr; // Only in the base class, must be protected!
};

// derivedprocess.h

#include "myprocess.h"

class DerivedProcessPrivate;
class DerivedProcess {
  Q_DECLARE_PRIVATE(DerivedProcess) // No semicolon!
public:
  explicit DerivedProcess(int arg, QObject * parent = 0);
  ~DerivedProcess();
}

// derivedprocess_p.h

#include "myprocess_p.h"

class DerivedProcessPrivate : public MyProcessPrivate {
  Q_DECLARE_PUBLIC(DerivedProcess) // No semicolon!
  //...
public:
  explicit DerivedProcessPrivate(DerivedProcess*);
};

// myprocess.cpp

MyProcess::MyProcess(int arg, QObject * parent) :
  QProcess(parent),
  d_ptr(new MyProcessPrivate(this)) {}

MyProcess::MyProcess(MyProcessPrivate & d, int arg) :
  d_ptr(&d) {}

MyProcessPrivate::MyProcessPrivate(MyProcess* parent) :
  q_ptr(parent) {}

// derivedprocess.cpp

DerivedProcess::DerivedProcess(int arg, QObject * parent) :
  MyProcess(* new DerivedProcessPrivate(this), arg, parent) {}

DerivedProcessPrivate::DerivedProcessPrivate(DerivedProcess* parent) :
  MyProcessPrivate(parent) {}
//myprocess.h
类别MyProcessPrivate;
类MyProcess:公共QProcess{
Q\u DECLARE\u PRIVATE(MyProcess)//没有分号!
公众:
显式MyProcess(int arg,QObject*parent=0);
~MyProcess();
受保护的:
MyProcess(MyProcessPrivate&,int arg,QObject*parent);//必须存在才能允许派生
const QScopedPointer d_ptr;//仅在基类中,必须受到保护!
}
//myprocess_p.h
类MyProcessPrivate{
Q\u DECLARE\u PUBLIC(MyProcess)//没有分号!
...
公众:
显式MyProcessPrivate(MyProcess*);
受保护的:
MyProcess*const q_ptr;//仅在基类中,必须受到保护!
};
//衍生过程
#包括“myprocess.h”
类派生的进程私有;
类派生过程{
Q\u DECLARE\u PRIVATE(DerivedProcess)//没有分号!
公众:
显式DerivedProcess(int arg,QObject*parent=0);
~DerivedProcess();
}
//衍生工艺
#包括“myprocess\u p.h”
类DerivedProcessPrivate:公共MyProcessPrivate{
Q\u DECLARE\u PUBLIC(DerivedProcess)//没有分号!
//...
公众:
显式DerivedProcessPrivate(DerivedProcess*);
};
//myprocess.cpp
MyProcess::MyProcess(int-arg,QObject*父对象):
QProcess(父进程),
d_ptr(新的MyProcessPrivate(this)){}
MyProcess::MyProcess(MyProcessPrivate&d,int-arg):
d_ptr(&d){}
MyProcessPrivate::MyProcessPrivate(MyProcess*父级):
q_ptr(父){}
//derivedprocess.cpp
DerivedProcess::DerivedProcess(int-arg,QObject*父对象):
MyProcess(*new-DerivedProcessPrivate(this),arg,parent){}
DerivedProcessPrivate::DerivedProcessPrivate(DerivedProcess*父级):
MyProcessPrivate(父级){}

可以通过d_ptr.data()访问它。 我想在不重新编译需要访问d_ptr的Qt源代码的情况下扩展QML的行为。下面是我如何在继承类中获得qdeclarativettedit的d_ptr中的QTextDocument:

QT_FORWARD_DECLARE_CLASS(QDeclarativeTextEditPrivate)
class MyTextEdit : public QDeclarativeTextEdit
{
  ...
  void aMethod()
  {
    QDeclarativeTextEditPrivate *d = reinterpret_cast<QDeclarativeTextEditPrivate *>(QDeclarativeItem::d_ptr.data());
    QTextDocument *d_doc = d->document;
    ...
  }
};
QT_FORWARD_DECLARE_类(qdeclarativettexteditprivate)
类MyTextEdit:PublicQDeclarativeTextEdit
{
...
void-aMethod()
{
qdeclarativettexteditprivate*d=reinterpret_cast(QDeclarativeItem::d_ptr.data());
QTextDocument*d_doc=d->document;
...
}
};
顺便说一句,我们也可以在不继承类的情况下获得d_ptr。 例如,以下是我如何在没有继承的情况下在QdeClarActivateExtenditPrivate中获取QTextDocument:

#include <QtGui/QGraphicsItem>
QT_FORWARD_DECLARE_CLASS(QGraphicsItemPrivate)
class DQGraphicsItem : public QGraphicsItem
{
  DQGraphicsItem() {}
public:
  QGraphicsItemPrivate *d() const { return d_ptr.data(); }
};

inline QGraphicsItemPrivate *d_qgraphicsitem(const QGraphicsItem *q)
{ return static_cast<const DQGraphicsItem *>(q)->d(); }

#include <qt/src/declarative/graphicsitems/qdeclarativetextedit_p.h>
#include <qt/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h>

inline QDeclarativeTextEditPrivate *d_qdeclarativetextedit(const QDeclarativeTextEdit *q)
{ return static_cast<QDeclarativeTextEditPrivate *>(d_qgraphicsitem(q)); }

inline QTextDocument *d_qdeclarativetextedit_document(const QDeclarativeTextEdit *q)
{ return d_qdeclarativetextedit(q)->document; }
#包括
QT_转发_声明_类(QGraphicsItemPrivate)
DQGraphicsItem类:公共QGraphicsItem
{
DQGraphicsItem(){}
公众:
QGraphicsItemPrivate*d()常量{返回d_ptr.data();}
};
内联qgraphicsitem私人*d_qgraphicsitem(const qgraphicsitem*q)
{return static_cast(q)->d();}
#包括
#包括
内联qdeclarativexteditprivate*d_qdeclarativextedit(常量qdeclarativextedit*q)
{return static_cast(d_qgraphicsitem(q));}
内联QTextDocument*d_qdeclarativettedit_文档(const qdeclarativettedit*q)
{return d_qdeclarativettedit(q)->document;}

您可以查看其他Qt类