[英]Overriding a member variable in C++
我在某些C ++代碼中遇到了一個棘手的問題,最容易使用代碼來描述。 我有一些類似的課程:
class MyVarBase
{
}
class MyVar : public MyVarBase
{
int Foo();
}
class MyBase
{
public:
MyBase(MyVarBase* v) : m_var(v) {}
virtual MyVarBase* GetVar() { return m_var; }
private:
MyVarBase* m_var;
}
我還擁有MyBase的子類,該子類需要具有MyVar類型的成員,因為它需要調用Foo。 不能將Foo函數移到MyVarBase中。 這樣做是否有意義:
class MyClass : public MyBase
{
public:
MyClass(MyVar* v) : MyBase(v), m_var(v) {}
MyVar* GetVar() { return m_var; }
private:
MyVar* m_var;
}
這似乎可行,但看起來確實很糟糕,我不確定是否會導致內存泄漏或破壞復制構造函數。 我的其他選擇可能是在MyClass中將MyVar變量命名為其他名稱,但使其等於基數中的m_var指針,或者在MyVar類型上對MyBase進行模板化。
所有這些選項似乎都不理想,因此我想知道是否有人遇到了這種情況,以及是否有使其工作的好方法。
正確的方法是僅在基類中具有變量。 如派生類所知,它必須是動態類型MyVar
,這是完全合理的:
class MyClass : public MyBase
{
public:
MyClass(MyVar* v) : MyBase(v) {}
MyVar* GetVar() { return static_cast<MyVar*>(MyBase::GetVar()); }
}
由於myvar可以從MyVarBase得出,不同的返回類型的GetVar
仍然堅持工作,如果GetVar是虛擬的(如這里的情況)。 請注意,使用該方法,在MyBase
中必須沒有任何函數可以將指針重置為明顯不同的內容。
請注意,在這種情況下, static_cast
是正確的轉換。 如一位評論者所建議,使用dynamic_cast
會告訴GetVar的讀者和用戶MyBase::GetVar()
可以返回指向非MyVar類型的對象的指針。 但這並不能反映我們的意圖,因為您只能通過MyVar。 因此,在軟件開發中最重要的是。 您可以做的是斷言它不是null。 它將在運行時中止,並在項目的調試版本中顯示錯誤消息:
MyVar* GetVar() {
assert(dynamic_cast<MyVar*>(MyBase::GetVar()) != 0);
return static_cast<MyVar*>(MyBase::GetVar());
}
在不了解更多上下文的情況下,很難確定,但是我首先要重新考慮您是否需要此類的類層次結構。 您是否真的需要MyVarBase和MyBase類? 您能擺脫合成而不是繼承嗎? 如果您將適用於上述類的函數和類模板化,那么也許根本就不需要類繼承。 也許CRTP也可以提供幫助。 在C ++中,有許多替代方法可以使用虛擬函數(在某種程度上,通常是繼承)。
無論如何,您自己建議的解決方案當然不會泄漏任何內存(因為它不會分配任何內存),也不會破壞默認的副本構造函數(因為它僅執行成員級副本。現在,您只需要一個額外的內存即可)派生類中的成員,但也會被復制)。 當然,您還會遇到使兩個變量保持同步的另一個問題,因此我仍然不太喜歡這種解決方案。
或者,您可以從基類中刪除變量。 使GetVar()函數成為純虛擬的,以便僅在派生類中實現,派生類可以按自己喜歡的任何方式定義成員變量。
我認為您提到模板可能是一個不錯的選擇,所以類似:
class MyVarBase
{
};
class MyVar : public MyVarBase
{
int Foo();
};
template <class T> class MyBase
{
public:
MyBase(T* v) : m_var(v) {}
T* GetVar() { return m_var; }
private:
T* m_var;
};
class MyClass : public MyBase<MyVar>
{
public:
MyClass(MyVar* v) : MyBase(v) {}
};
但是,這取決於您可以實際更改的類。 同樣,“ MyClass”定義可能是多余的,除非它具有MyBase類之外的其他成員。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.