2010-05-20 154 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; 
};