首先,我們要介紹的基本知識。 IANAL,但這裏是:
我認爲你有一個封閉源代碼的應用程序,希望根據LGPL的條款使用Qt。
根據美國法律的一些解釋,使您的代碼依賴於Qt的私有頭文件使其成爲Qt的派生工作,因此您的代碼必須可以根據LGPL(或GPL)提供,除非您擁有商業許可證。
你在LGPL下的義務是讓你分發你的應用程序的人可以用他們編譯的Qt版本重新鏈接你需要提供給他們的源代碼。這可能是由操作系統完成的動態鏈接,或者是使用鏈接器實用程序完成的靜態鏈接。無論您是否修改Qt都無關緊要。他們問,你必須向他們提供你用來構建你在應用中使用的Qt的精確構建腳本。
當你依賴私有頭文件時,某些人不可能對你提供的Qt版本進行二進制兼容的修改,並用你的代碼重新鏈接它,而不會中斷任何事情。私有Qt類可以在不破壞二進制兼容性的情況下進行更改 - 這就是爲什麼它們是私有的。我自己我解釋LGPL如下:我的代碼是不是派生的工作,如果它將成功地鏈接和任何版本的Qt的工作,這是與我的應用程序提供的版本二進制兼容的版本。當然,這是Qt錯誤和其他更改的限制,因此某些人可能無法將此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) {}
你可以看看其他的Qt類,看看他們是如何做到這一點 –
內的Qt本身,這是通過廣泛利用友元類的將涉及解決更改代碼 – user1723056
@ user1723056要修補Qt的PIMPL層次結構,您只需包含私有頭文件,不需要更改代碼,但我不鼓勵這樣做 - 除非您正在編寫一個類,否則實際上毫無意義大量實例化。 –