1. 程式人生 > >兩個類相互引用的解決方法

兩個類相互引用的解決方法

1 問題提出

最近在編寫“鬥地主”遊戲,在程式中有一個“CDealer”類用來實現發牌等等功能,還有一個“CPoker”類,用來表示撲克牌。在CDealer類中包含了一個CPoker類指標的成員變數,而在CPoker類中也包含了一個CDealer類指標的成員變數,如下所示:

//CPoker類標頭檔案

#pragma once

#include "Dealer.h"

class CPoker

{

public:

    CPoker(void);

    ~CPoker(void);

private:

    CDealer *m_pDealer;

};

//CDealer類的標頭檔案

#pragma

once

#include "Poker.h"

class CDealer

{

public:

    CDealer(void);

    ~CDealer(void);

private:

    CPoker *m_pPoker;

};

程式編譯時,錯誤提示為

poker.h(10) :error C2143: 語法錯誤: 缺少“;”(在“*”的前面)

poker.h(10) :error C4430: 缺少型別說明符- 假定為int。注意: C++ 不支援預設int

2 問題分析

因為在程式中首先包含的是Dealer.h,所以Dealer.h標頭檔案首先被編譯。如圖3-1所示。在CDealer類的標頭檔案中,第1步執行了#pragma once之後就進入到第2步,即Poker.h標頭檔案中。在Poker.h標頭檔案中進行第3步,執行#pragma once,之後進入到第4步,也就是Dealer.h中,由於Dealer.h中包含#pragma once,並且此時已經被編譯,所以第4步中的#include “Dealer.h”實際上沒有執行,繼續進行到Poker.h的第5步,定義CDealer類的指標,此時CDealer類實際上還沒有定義,因此編譯時回報錯。

3 問題解決

3.1 類的前向宣告

從2中分析可以看到,報錯的主要原因是CDealer類沒有定義。可以使用類的前向宣告(forwarddeclaration)的方式解決這個問題。如

class CDealer;


圖3-1 標頭檔案執行流程

在CPoker類定義中映入了類型別CDealer。在類宣告之後而定義之前,類CDealer是一個不完全型別(incompetetype),即已知CDealer是一個類,但不知道包含哪些成員,所以使用類的前向定義後,只能宣告該類的指標,而不是該類的物件。

同理,在Dealer.h中加入CPoker類的前向宣告。

classCPoker;

3.2 將包含標頭檔案的程式碼放到執行檔案

儘量將包含標頭檔案的語句放到執行檔案(.cpp檔案)中而不是在標頭檔案中(.h檔案)。因此,接下來將#include“Poker.h”語句放到Dealer.cpp檔案中,而將#include“Dealer.h”語句放到Poker.cpp檔案中。

4 小結

對於兩個類間相互引用引發的編譯錯誤,可以使用類前向宣告的方式解決。類前向宣告是一個不完整型別,只能使用其指標。儘量將包含標頭檔案的程式碼放在cpp執行檔案中,而不是h標頭檔案中。