[英]Class name does not name a type in C++
我剛開始在 C++ 編程,我嘗試創建 2 個類,其中一個包含另一個。
文件Ah
:
#ifndef _A_h
#define _A_h
class A{
public:
A(int id);
private:
int _id;
B _b; // HERE I GET A COMPILATION ERROR: B does not name a type
};
#endif
文件A.cpp
:
#include "A.h"
#include "B.h"
#include <cstdio>
A::A(int id): _id(id), _b(){
printf("hello\n the id is: %d\n", _id);
}
檔案Bh
:
#ifndef _B_h
#define _B_h
class B{
public:
B();
};
#endif
文件B.cpp
:
#include "B.h"
#include <cstdio>
B::B(){
printf("this is hello from B\n");
}
我首先編譯 B class,然后編譯 A class,但隨后我收到錯誤消息:
Ah:9: 錯誤:'B' 沒有命名類型
我該如何解決這個問題?
預處理器將文件Ah
和Bh
的內容准確地插入到include
語句出現的位置(這實際上只是復制/粘貼)。 當編譯器隨后解析A.cpp
,它會在知道類B
之前找到類A
的聲明。 這會導致您看到的錯誤。 有兩種方法可以解決這個問題:
Ah
包含Bh
。 在需要的文件中包含頭文件通常是一個好主意。 如果您依賴於通過另一個頭文件的間接包含,或編譯單元(cpp 文件)中包含的特殊順序,這只會隨着項目變大而使您和其他人感到困惑。 如果在類A
使用類型B
成員變量,編譯器需要知道B
的准確和完整聲明,因為它需要為A
創建內存布局。 另一方面,如果您使用的是指向B
的指針或引用,那么前向聲明就足夠了,因為編譯器需要為指針或引用保留的內存與類定義無關。 這看起來像這樣:
class B; // forward declaration class A { public: A(int id); private: int _id; B & _b; };
這對於避免標頭之間的循環依賴非常有用。
我希望這會有所幫助。
error 'Class' does not name a type
以防萬一有人做了我做過的同樣愚蠢的事情......我正在從頭開始創建一個小型測試程序,我輸入了Class而不是class (帶有一個小 C)。 我沒有注意到錯誤消息中的引號,並且花了太長時間不理解我的問題。
我對解決方案的搜索將我帶到了這里,所以我想其他人也可能會遇到同樣的情況。
注意:因為使用相同關鍵字搜索的人將登陸此頁面,所以我添加了這個答案,這不是上述情況下編譯器錯誤的原因。
當我在某個文件中聲明了一個enum
時,我遇到了這個錯誤,其中一個元素與我的類名具有相同的符號。
例如,如果我在某個文件中聲明一個enum = {A, B, C}
該文件包含在我聲明class A
對象的另一個文件中。
這引發了相同的編譯器錯誤消息,其中提到Class A does not name a type
。 在我的情況下沒有循環依賴。
因此,在 C++ 中命名類和聲明枚舉(可能在其他文件中可見、導入和外部使用)時要小心。
您必須首先包括Ah
Bh
。 B b
; 在您包含Bh
之前沒有任何意義。
在“啊”中包含“Bh”。 這會在編譯“A”時為編譯器帶來“B”的聲明。
第一個要點適用於 OP。
3.4.1/7 美元 -
“在成員函數體或嵌套類定義之外的類 X 的定義中使用的名稱應以下列方式之一聲明:
—在 X 類中使用之前或成為 X 基類的成員(10.2),或
— 如果 X 是 Y 類 (9.7) 的嵌套類,在 Y 中 X 的定義之前,或者應該是 Y 的基類的成員(此查找依次適用於 Y 的封閉類,從最內部的封閉類開始),28) 或
— 如果 X 是本地類 (9.8) 或本地類的嵌套類,則在包含類 X 定義的塊中的類 X 定義之前,或
— 如果 X 是命名空間 N 的成員,或者是作為 N 成員的類的嵌套類,或者是作為 N 成員的函數的局部類中的局部類或嵌套類,則在命名空間 N 或 N 的封閉命名空間之一中的類 X 的定義。”
問題是你需要在你的Ah
文件中包含Bh
。 問題是在A
的定義中,編譯器仍然不知道B
是什么。 您應該包括您正在使用的所有類型的所有定義。
當您定義類 A 時,在 Ah 中,您明確地說該類有一個成員 B。
您必須在“Ah”中包含“Bh”
你不是錯過了 Ah 中的 #include "Bh" 嗎?
我今天的問題的解決方案與這里的其他答案略有不同。
就我而言,問題是由包含鏈中的一個頭文件末尾缺少右括號 ( }
) 引起的。
本質上,發生的事情是A
包括B
。 由於B
缺少一個}
在文件中的某個地方,在定義中B
沒有被正確的找到A
。
起初我以為我有循環依賴並添加了前向聲明B
。 但隨后它開始抱怨B
中的某些東西是不完整的類型。 這就是我想到仔細檢查文件是否存在語法錯誤的方式。
嘗試移動所有包含外部命名空間的內容。
//Error
namespace U2 {
#include <Head.h>
#include <LifeDiode.h>
}
//解決方案
#include <Head.h>
#include <LifeDiode.h>
namespace U2 {
}
不是答案,但對我來說,問題是我忘記在潛在類型之前添加std::
以正確使用它。
它實際上發生在我身上,因為我錯誤地將源文件命名為“something.c”而不是“something.cpp”。 我希望這可以幫助有同樣錯誤的人。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.