我试图了解我整个d指针的工作方式。我拥有大部分零件,但目前面临一个问题:

就像这里的Dpointer inheritance一样,我想使用d指针继承一个类(实际上它是QProcess)。

由于访问d指针的功能是私有(private)的,因此我无法通过简单继承来访问它。我的想法是再次使用Q_DECLARE_PRIVATE宏来获取该函数并对其进行访问。能行吗?在尝试之前,我需要一些提示,因为我不知道这样是否可以工作。

(我需要这样做以避免整个许可问题。)

我的进程

#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;
}

最佳答案

首先,让我们介绍一下基础知识。 IANAL,但是在这里:

我假设您有一个希望在LGPL条款下使用Qt的开源应用程序。

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

LGPL的义务是使您分发应用程序的人们能够与您从有义务向他们提供的来源编译的Qt版本重新链接。这可能是由OS完成的动态链接,也可能是由链接器实用程序完成的静态链接。是否修改Qt都没有关系。他们问,您必须向他们提供Qt源,并提供与您用来构建应用中使用的Qt的确切构建脚本相同的脚本。

当您依赖私有(private) header 时,对于某人您不可能对您提供的Qt版本进行二进制兼容的更改并将其与您的代码重新链接,而不会发生任何问题。可以在不破坏二进制兼容性的情况下更改私有(private)Qt类-这就是为什么它们是私有(private)的。我本人对LGPL的解释如下:如果我的代码可以成功链接并与与我的应用程序一起提供的二进制版本兼容的任何Qt版本,则我的代码不是派生工作。当然,这在Qt错误和我所做的其他更改的范围内,因此对于某人将此Qt修补到较旧的版本并希望其运行正常可能不可行。

因此,唯一可以使代码保持源代码封闭的方法是在Qt内修改QProcess的* public接口(interface)。任何人都可以使用此Qt的修改版本(您提供的!),对其进行进一步的二进制兼容更改,然后重新链接您的代码。因此,如果您认为不修改Qt并依赖于私有(private) header 使您的生活更轻松,那么您将与基本脱节。

一般来说,您不能从QXyzPrivate继承,因为您需要包括Qt的私有(private) header 。因此,这不是一个好习惯,而且确实没有充分的理由这样做。实例化类时,您要付出的代价是额外的堆分配,所以我说不用担心。

您必须启动自己的私有(private)PIMPL类层次结构。请注意,要派生的每个类如何必须提供一个引用私有(private)类实例的构造函数。

// 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) {}

关于c++ - Qt访问继承类的D指针,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21336527/

10-08 22:03
查看更多