關於兩個類相互包含引用的思考

2021-08-07 04:00:46 字數 1678 閱讀 1909

今天遇到乙個問題,編譯時遇到了如下錯誤:

錯誤1 error c2146: 語法錯誤: 缺少「;」(在識別符號「move」的前面)

錯誤2 error c4430: 缺少型別說明符 - 假定為 int。注意:  c++ 不支援預設 int

寫個最簡單的例子:

#ifndef __robot_h__

#define __robot_h__

#include "move.h"

class crobot

;#endif

#ifndef __move_h__

#define __move_h__

#include "robot.h"

class cmove

;#endif

這兩個類互相定義了對方的乙個物件,這其實是不可能的。編譯器肯定是順序地解析,比如先解析robot.h,include了cmove的定義,此時還未開始解析crobot的定義,但是cmove的定義卻依賴於crobot的定義,因為在cmove中定義了crobot的物件。這顯然不行。所以,一般來說,兩者的定義,至少有一方是使用指標,或兩者都使用指標,但是不能兩者都定義實體物件

好,接下來看下面這樣

#ifndef __robot_h__

#define __robot_h__

#include "move.h"

class crobot

;#endif

#ifndef __move_h__

#define __move_h__

#include "robot.h"

class cmove

;#endif

那麼這樣行不行呢?  答案是編譯器仍然報錯

在編譯crobot時,include了move.h,其實就是拷貝,由於#ifndef的效果,robot.h不會被二次包含,所以相當於下面這樣

class cmove

;class crobot

;這個時候對於cmove來說,crobot仍然是不可見的,因為其定義在後面,所以其實需要乙個crobot的乙個前向宣告。

注:宣告的類型別可以用來定義指標或引用,但是不能定義物件,因為僅僅是宣告,在編譯器看來,指標和引用的大小是確定的。但是定義物件就需要知道確切的類定義,這樣編譯器才能知道類大小(編譯器需要在編譯期知道物件所佔空間大小)

所以在crobot中還是需要include cmove類,需要知道其定義

但是對於cmove來說,其僅僅需要知道crobot的宣告,不需要include其標頭檔案,只需要乙個前向宣告。但是我在vs 2013上試了一下,加乙個前向宣告再include robot.h,這樣也是通不過編譯的,不知道為什麼??????

#ifndef __move_h__

#define __move_h__

class crobot;

#include "robot.h"

class cmove

;#endif

一般的做法是:兩個類的標頭檔案之中,選乙個包含另乙個類的標頭檔案,但另乙個標頭檔案中只能採用class *的宣告形式,自然只能定義指標或者引用,而在實現檔案中(*.cpp)中包含標頭檔案。當然,用類定義物件的檔案一定得包含標頭檔案

可以參考下以下部落格:

兩個類相互包含引用的問題

在構造自己的類時,有可能會碰到兩個類之間的相互引用問題,例如 定義了類a類b,a中使用了b定義的型別,b中也使用了a定義的型別 class a class b 請注意上面的定義內容,一般情況下是不能出現類a,類b相互引用都定義物件,即如下的樣子 class a class b 在這種情況下,想想能夠...

兩個類相互包含引用的問題

1 背景 程式設計中遇到如下錯誤 使用不完全型別 以及 前向宣告。查詢相關資料後發現是類的前向宣告 forward declaration 問題 在程式中宣告乙個類後,此類是乙個不完全型別 incompete type 即已知此類是乙個型別,但不知道包含哪些成員。不完全型別 只能以有限方式使用,不能...

c 兩個類相互包含引用的問題

在構造自己的類時,有可能會碰到兩個類之間的相互引用問題,例如 定義了類a類b,a中使用了b定義的型別,b中也使用了a定義的型別 class a class b 請注意上面的定義內容,一般情況下是不能出現類a,類b相互引用都定義物件,即如下的樣子 class a class b 在這種情況下,想想可以...