2013-03-19 122 views
1

我有此代码,请注意,两行已注释成员变量继承

#include <iostream> 

class foo { 
public: 
    foo(); 
    int i; 
}; 

class bar: foo { 
public: 
    bar(); 
    //int i; 
}; 

foo::foo() 
{ 
    i = 2; 
} 

bar::bar() 
{ 
    i = 4; 
} 

int main() 
{ 
    bar *b = new(bar); 
    //std::cout << "bi = " << b->i << std::endl; /*line 28*/ 
    foo *f = (foo*) b; 
    std::cout << "fi = " << f->i << std::endl; 
} 

随着注释掉两行,代码编译和输出是

fi = 4 

通过这两个代码编译和输出是

bi = 4 

fi = 2 

只有i wit的声明欣类吧注释掉编译失败

var.cc: In function ‘int main()’: 

var.cc:6:7: error: ‘int foo::i’ is inaccessible 

var.cc:28:30: error: within this context 

我理解前两种情况,但我不明白这个编译错误。为什么

变量“我”可以从酒吧的构造函数,但不是从一个酒吧指针?

+0

尝试从富公开'类酒吧继承:公共foo' – StoryTeller 2013-03-19 11:19:49

回答

3

在私有继承中,基类的所有成员都变成private派生类的成员。请注意,对于类,如果未指定任何默认继承,则为private

i由于充当的bar一个private构件,它可以在bar::bar()被访问而不是从构件的功能之外。

良好阅读:

What are access specifiers? Should I inherit with private, protected or public?

+0

啊,并且默认情况下继承是私有的。公开继承允许它编译,输出是bi = 4 fi = 4.谢谢。 – 2013-03-19 11:22:38

+0

@RichardJohnson:看看我在回答中提供的链接。它应该解释你的一切。 – 2013-03-19 11:23:34

+0

感谢您提供该链接,它非常丰富。我可能需要再次阅读(也可能再次)才能获得所有的细节。 – 2013-03-19 11:32:27

1

这样做的原因是,你正在使用私有继承

对于所有class es,private是默认访问修饰符。这意味着成员和基地是private,除非另有说明。

但对于struct,默认值为public。的确,这是classstruct之间的唯一区别。

因此,在编写class bar: foo时,这相当于class bar: private foo

要解决此问题,您需要执行class bar: public foostruct bar: foo,这两者在您的示例中都相同(因为您没有使用默认访问修饰符的成员)。

0

您应该直接指定字段的名称范围,如果他们在不同的班级同一个名字:

struct s1 
{ 
    int i; 
}; 

struct s2 : public s1 
{ 
    int i; 
}; 

int main() 
{ 
    s2 v; 

    v.s1::i = 1; 
    v.s2::i = 2; 

    std::cout << v.s1::i << v.s2::i << std::endl; 

    return 0; 
} 

输出将是12