2010-05-20 152 views
1

這裏是我的代碼 -繼承和靜態變量

#include <iostream> 
#include <conio.h> 

using namespace std; 

class Base 
{ 
public: 
int a; 

}; 

//int Base::a = 5; 

class Derived : public Base 
{ 

public: 
int static a; 
}; 

int main() 
{ 
    Derived d; 
    cout<<d.a; 
    getch(); 
    return 0; 
} 

我在這裏得到一個連接錯誤。但當我這樣做時,相反 -

class Base 
{ 
public: 
int static a; 

}; 

int Base::a = 5; 

class Derived : public Base 
{ 

public: 
int a; 
}; 

我沒有得到任何錯誤。有人能解釋一下這裏發生了什麼嗎?

+1

沒有答案,但爲什麼你的事件想要2個對象相同的變量名。只是添加混淆(即使對鏈接器) – RvdK 2010-05-20 07:03:12

+0

@PoweRoy:鏈接器不會在意 - 它使用裝飾名稱。 – sharptooth 2010-05-20 07:04:10

+0

@PoweRoy:沒有理由只是修修補補周圍 – Bruce 2010-05-20 07:07:11

回答

6

所有靜態成員必須被明確定義/外部類初始化。

在第二個範例這樣做正確(INT基準:: A = 5),但在第一個例子中沒有爲衍生::一個,將下面的行第一示例應該解決它這樣做:

int Derived::a = 5; 
+0

是它解決了錯誤,但爲什麼犯規編譯器給出錯誤的變量的多個聲明?繼承時是否允許靜態升級/降級? – Bruce 2010-05-20 07:06:03

+2

派生::一個簡單地否決基地::一個,就像在一個碼塊定義一個變量i覆蓋塊外的相同命名的變量。這是完全合法的。考慮使用靜態代碼分析工具(如PCLint)來發現這種難以發現的問題。 – Patrick 2010-05-20 07:08:10

+0

只是出於好奇...這是允許在Java中嗎? – Bruce 2010-05-20 07:13:56

2

您需要實際定義靜態成員。用同樣的方法,你在第二種情況下做

int Base::a = 5 

你應該在第一種情況下完成

int Derived::a = 5; 

1

這裏有兩個問題。 首先是爲什麼你在第一個例子中遇到鏈接器錯誤? 那麼,在第一個例子中你會得到一個鏈接錯誤,因爲你沒有定義/初始化B類的靜態成員。

第二個問題是爲什麼編譯器不會抱怨多個聲明? 編譯器不抱怨多次聲明,因爲就它而言,這兩個變量在不同的範圍和他們的錯位的名稱會有所不同呢。這與其中一個變量是靜態的無關。實際上,靜態成員甚至不被繼承。所以,沒有靜態變量的下面的代碼片段也是正確的:

class B { 
public: 
int a; 
}; 

class C: public B { 
public: 
int a; 
};