所有解決方案,以圓形包括我看過只是「這種特殊情況下」,因爲「你」僅使用指針該類完整的類定義是沒有必要說的依賴性。循環包括依賴性/前置聲明
我遇到了這個問題,並使用前置聲明固定它。
我想知道什麼是你應該在你需要的其他類的兩個類的具體定義做。
而且,爲什麼使用指針類允許您使用正代替聲明一個類定義的?
所有解決方案,以圓形包括我看過只是「這種特殊情況下」,因爲「你」僅使用指針該類完整的類定義是沒有必要說的依賴性。循環包括依賴性/前置聲明
我遇到了這個問題,並使用前置聲明固定它。
我想知道什麼是你應該在你需要的其他類的兩個類的具體定義做。
而且,爲什麼使用指針類允許您使用正代替聲明一個類定義的?
在什麼情況下您需要事先知道兩個類的規格?
一個不可能的情況是以下內容:
class A
{
B m_b;
};
class B
{
A m_a;
};
但是,由於類A的大小依賴於類B的大小,這是不可能的,但類B的大小取決於類A的大小當您嘗試構建其中一個時,您還將獲得無限系列A myA; myA.m_b.m_a.m_b.m_a....
。
如果你使用指針,你不需要知道的任何大小;指針總是相同的大小取決於你所在的平臺。系列消失了,因爲需要明確創建堆中的對象。
我想知道什麼是你應該當你需要在這兩個類別的具體 定義其他類做。
它可以用現代編譯器中的前向聲明和延遲定義完成。許多較早的編譯器只允許指向&引用前向聲明的類型。
下面是一個人爲的例子:
A.hpp
class B;
class A
{
public:
int32_t Value;
A(int32_t value) : Value(value) { }
int32_t Add(B b) const;
}
B.hpp
#include "A.hpp"
class B
{
public:
int32_t Value;
B(int32_t value) : Value(value) { }
int32_t Sub(A a) const;
}
AB.hpp
#include "A.hpp"
#include "B.hpp"
inline int32_t A::Add(B b) const
{
return this->Value + b.Value;
}
inline int32_t B::Sub(A a) const
{
return this->Value - a.Value;
}
此外,爲什麼使用指向類的指針允許您使用正向 聲明而不是類定義?
正向聲明只是名稱的編譯器。這個概念存在,所以你可以使用尚未定義的類型而。這是必要的,因爲C++分析代碼的方式,它是C語言的一個非常重要的部分。 C++解析器實際上僅僅是隻向前文本處理器,在您使用宏時注入文本。這是一個概念上簡單的模型,它使得C/C++編譯器在早期更容易編寫。將它與C#/ Java進行對比,您只需使用/ import,然後用簡單的語法快速創建類之間的循環依賴關係。
指針實際上只是整數,與short
和int
類似,但是具有語言強制的特殊語義和基於CPU架構的編譯時已知的固定大小。這使編譯器處理指針聲明非常簡單。
前向聲明有利於循環依賴和實現隱藏(這也正好加快了編譯時間)。考慮pimpl idiom。沒有前向聲明,沒有類型安全的方法來隱藏實現細節。
我想到的一個例子是對象「A a」創建對象「B b」,但是在構造或道路某個點傳遞它自身的副本。但是「對象b」有一個類型爲A的成員變量。 我很確定你會這樣做的任何情況都會被認爲是糟糕的編程,但那是困擾我的問題。 感謝您的全面回答! – Spectral
「傳遞給它一個副本」 - 你可以聲明一個函數,將一個不完整的類作爲參數或返回類型傳遞;直到看到類定義完成後才能定義或調用它。所以'A級; B類{public:void process(A); };'很好。 (即使在那裏,你可以使用'const A&'。) – aschepler