我有这段代码,请注意两行已被注释掉
#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”可以从条形构造函数中访问,但不能从条形指针访问?
答案 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
。实际上,这是class
和struct
之间唯一的区别。
因此,在撰写class bar: foo
时,这相当于class bar: private foo
。
要解决此问题,您需要执行class bar: public foo
或struct 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