首先,让我们介绍一下基础知识。IANAL,但它是这样的:
我假设您有一个希望根据 LGPL 条款使用 Qt 的闭源应用程序。
根据美国法律的某些解释,使您的代码依赖于 Qt 的私有标头使其成为 Qt 的派生作品,因此您的代码必须在 LGPL(或 GPL)条款下可用,除非您拥有商业许可。
您在 LGPL 下的义务是让您分发您的应用程序的人能够将其与他们从您有义务提供给他们的源代码编译的 Qt 版本重新链接。这可能是由操作系统完成的动态链接,或使用链接器实用程序完成的静态链接。你是否修改了 Qt 并不重要。他们问,您必须向他们提供 Qt 源代码,其中包含用于构建您在应用程序中使用的 Qt 的确切构建脚本。
当您依赖私有标头时,某人不可能对您提供的 Qt 版本进行二进制兼容的更改并将其与您的代码重新链接,而不会造成任何破坏。可以在不破坏二进制兼容性的情况下更改私有 Qt 类——这就是它们是私有的原因。我自己对 LGPL 的解释如下:如果我的代码能够成功链接并与任何与我随应用程序一起提供的版本二进制兼容的 Qt 版本一起工作,那么我的代码就不是派生工作。当然,这在我所做的 Qt 错误和其他更改的范围内,因此将这个 Qt 修补到旧版本并期望它运行正常可能是不可行的。
因此,保持代码封闭源的唯一方法是修改QProcess
Qt 中的 *public 接口。任何人都可以使用这个修改过的 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) {}