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

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”可以从 bar 构造函数中访问,但不能从 bar 指针访问?

4

3 回答 3

3

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

由于i作为 的private成员bar,它可以在成员函数内部访问,bar::bar()但不能从成员函数外部访问。

好读:

什么是访问说明符?我应该以私有、受保护还是公共继承?

于 2013-03-19T11:17:47.090 回答
1

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

对于所有classes,private是默认的访问修饰符。这意味着private除非另有说明,否则成员和基础都是。

但是,对于 a struct,默认值为public. class事实上,这是 a和 a之间的唯一区别struct

因此,在编写 时class bar: foo,这等价于class bar: private foo

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

于 2013-03-19T11:20:42.203 回答
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

于 2013-03-19T11:21:48.763 回答