2011-08-11 80 views
1

我想知道是否有人可以向我解釋這個宏。C++宏導致空指針

#define Q_DECLARE_PRIVATE(Class) \ 

inline Class##Private* d_func() { return reinterpret_cast<Class##Private 
*>(d_ptr); } \ 

inline const Class##Private* d_func() const { return reinterpret_cast<const 
Class##Private *>(d_ptr); } \ 

friend class Class##Private; 

我有一個使用QT的應用程序,它在以下代碼片段的最後一行中發生訪問衝突異常時崩潰。

class Q_GUI_EXPORT QWidget : public QObject, public QPaintDevice 
{ 
    Q_OBJECT 
    Q_DECLARE_PRIVATE(QWidget) 

full source here

,什麼可以在最後一行導致空指針操作?

回答

3

編譯器可以解釋它最重要的是:

g++ -E foo.cc 

將會把foo.cc經過前處理後,到標準輸出。它可以讓你看到編譯器看到哪些內容(尤其是使用令牌粘貼)通常不太明顯。

1

是你的this指針NULL?所有代碼都會爲d_ptr類成員生成訪問函數。

+0

當我實例化一個繼承自'QListView'的類時,這條線被擊中,從QWidget中間接繼承問題中顯示的QWidget。 –

+0

當異常發生時,您可以確認'this'指針是否爲NULL? –

1

這個宏通過聲明一個私有實現類的指針來實現一個Pimpl習語。 ##垃圾正在使用預處理器連接運算符爲專用類創建一個名稱。

如果檢索d_ptr成員導致NULL訪問,則調用者必須做NULL->d_func()。尋找並調試調用者。

1

從Windows頭:

#define DECLARE_HANDLE(name) struct name##__ {int unused;} typedef name##__* name; 

與用法:

DECLARE_HANDLE(YourHandeType); // Just any name, this isn't any type 

將創建新的結構爲:

struct YourHandleType__ 
{ 
    int unused; 
}; 
typedef YourHandleType__ * YourHandleType; 

YourHandleType將類型的指針YourHandleType__

預處理器將使用標記化程序運算符##來創建全名,C/C++編譯器將使用該全名。在這種情況下,DECLARE_HANDLE可以創建對調用者不透明的不同類型,並且仍然在不同的句柄之間提供「不轉換」。