2012-11-16 61 views
0

考慮從WinAPI的這個類:C++ - 與對象名稱typedef結構的正向聲明

typedef struct tagRECT 
{ 
    LONG left; 
    LONG top; 
    LONG right; 
    LONG bottom; 
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT; 

我提高它在一個名爲Rect類,它可以讓你乘/加/減/比較兩個Rect小號,以及其他功能。我需要我的Rect類知道RECT的唯一真正原因是因爲該類具有一個轉換運算符,該運算符允許RectRECT的形式傳遞,並被分配爲RECT

但是,在文件Rect.h中,我不想包含<Windows.h>,我只想在源文件中包含<Windows.h>,這樣我可以保留包含樹很小。

我知道結構可以向前聲明如下這樣:struct MyStruct; 但是,該結構的實際名稱爲tagRECT,它有一個對象列表,所以我也有點困惑,如何轉發聲明。這是我的班級的一部分:

// Forward declare RECT here. 

class Rect { 
    public: 
     int X, Y, Width, Height; 

     Rect(void); 
     Rect(int x, int y, int w, int h); 
     Rect(const RECT& rc); 

     //! RECT to Rect assignment. 
     Rect& operator = (const RECT& other); 

     //! Rect to RECT conversion. 
     operator RECT() const; 

     /* ------------ Comparison Operators ------------ */ 

     Rect& operator < (const Rect& other); 
     Rect& operator > (const Rect& other); 
     Rect& operator <= (const Rect& other); 
     Rect& operator >= (const Rect& other); 
     Rect& operator == (const Rect& other); 
     Rect& operator != (const Rect& other); 
}; 

這是有效的嗎?

// Forward declaration 
struct RECT; 

我的想法是沒有的,因爲RECT只是tagRECT的別名。我的意思是,如果我這樣做,我知道頭文件仍然有效,但是當我創建源文件Rect.cpp並在其中包含<Windows.h>時,我擔心這是我遇到問題的地方。

我該如何轉發聲明RECT? 提前:)感謝

+0

只是一個說明。我做了同樣的事情,我也想要一個RECT結構的增強版本。最後,我的結構派生自RECT,因爲當使用期望RECT爲參數的winapi函數時,不需要投射。我發現這是一個更好的解決方案,您可能會考慮到這一點 – roohan

+0

@ user1017443這是一個好主意。我最初考慮過這個問題,但是我決定反對它,因爲我想要'寬度'和'高度'而不是'cx'和'cy'。其中,這可能不是一個很好的藉口,因爲看到這種方式需要更多的關於課堂用戶的文章。 –

+0

但是要麼在文件中包含''。 –

回答

2

在實際取消引用類型之前,您不需要知道函數定義。

所以,你可以轉發在頭聲明文件(因爲你不會在這裏做任何非關聯),那麼在您文件Windows.h

沒有看到它是一個typedef。但是,其他答案是錯誤的:there is a way to (kind of) forward declare a typedef

+1

謝謝,不知道。這當然不是一個好習慣,但在這種情況下,這是M $的錯,不是OP的錯。這不是一個真正的typedef前向聲明,而是需要兼容的多個聲明。 – Potatoswatter

+0

如果某些東西被聲明爲「extern」C「'或不是,這會有什麼不同嗎?我想知道是否有任何的Windows頭文件是這樣聲明的,以及可能產生的效果。 –

+0

@Kevin大概C接口是,但'extern「C」'是一個鏈接修飾符,類型和typedefs沒有鏈接,所以它應該沒關係。 – Potatoswatter

3

您可以乘聲明typedef名稱,也向前同時聲明結構名稱:

typedef struct tagRECT RECT; 

https://ideone.com/7K7st7

注意,你不能打電話一個返回不完整類型的函數,因此如果tagRECT只是前向聲明,則不能調用operator RECT() const轉換。

+0

你實際上可以轉發聲明一個typedef(剛剛發現了這個,請參閱我的答案中的鏈接) –

+0

@MaëlNison:它實際上不是typedef的前向聲明,而是一個完整的typedef(不完整類型)。 –