2015-05-28 44 views
0
class Class1 { 
Class1() { Class2::counter++;} 
} 

class Class2: public Class1 { 
public: 
static int counter; 
} 

以上是我正在嘗試做的一個示例。我想在超類中使用一個子類的靜態變量,但這給了我一個編譯器錯誤,因爲Class1首先被初始化,當編譯器到達Class2 :: counter ++;它尚未初始化Class2,因此我得到「Class2尚未聲明」錯誤。我怎樣才能解決這個問題?我需要完全改變我的邏輯嗎?在超類中使用子類的靜態變量

回答

0

您可能後Class2定義把構造Class1的定義:

class Class1 { 
public: 
    Class1(); 
}; 

class Class2: public Class1 { 
public: 
    static int counter; 
}; 

int Class2::counter = 0; 

Class1::Class1() { Class2::counter++;} 

Live demo

+0

我想我會用這個,因爲它只需要對我的代碼進行最少的更改 – JimS

1

你可以只通過一個引用您的計數器基類:

class Class1 { 
public: 
    Class1(int& counter) { ++counter; } 
}; 

class Class2: public Class1 { 
public: 
    static int counter; 
    Class2() : Class1(counter) { } 
}; 

int Class2::counter = 0; 
0

經驗法則:基類不訪問子類成員或方法

如果基類需要某個子類的某些東西,則在基類中聲明一個抽象的虛函數,以便子實現。

或將公共數據成員或方法移動到基類中。

你的情況:

class Base 
{ 
    virtual void increment_counter(void) = 0; 
    void my_method(void) 
    { 
    increment_counter(); 
    } 
}; 

class Child : public Base 
{ 
    int counter; 
    void increment_counter(void) 
    { 
    ++counter; 
    } 
}; 
2

從OOP的角度父類是不能夠訪問對於子字段或屬性,它應該與孩子訪問父字段或屬性的方式相反。我想知道你是否需要從父母那裏訪問tora兒童領域?如果您提供更多詳細信息,您試圖達到的最佳解決方案將由某人提供。

0

只需在Class2的定義之後定義類Class1的構造函數即可。

class Class1 { 
public: 
Class1(); 
} 

class Class2: public Class1 { 
public: 
static int counter; 
} 

Class1::Class1() { Class2::counter++;} 

不要忘記定義Class2中的靜態數據成員。:)

0

如果你想獲得怪異使用模板,這聽起來對curiously recurring template pattern一個可能的用途。例如:

template <typename T> 
class CRTBase 
{ 
    CRTBase() { T::counter++; } 
}; 

class CRTDerived : public CRTBase<CRTDerived> 
{ 
public: 
    static int counter; 
}; 

int CRTDerived::counter = 0;