成员变量继承

时间:2013-03-19 11:15:24

标签: c++

我有这段代码,请注意两行已被注释掉

#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声明注释掉编译失败

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

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

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

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

变量“i”可以从条形构造函数中访问,但不能从条形指针访问?

3 个答案:

答案 0 :(得分:3)

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

由于i充当private的{​​{1}}成员,因此可以在bar中访问,但不能从成员函数外部访问。

好读:

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

答案 1 :(得分:1)

原因是您使用的是私有继承

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

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

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

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

答案 2 :(得分: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