[英]C++ simple inheritance problem
#include <iostream>
using namespace std;
class A
{
protected:
int a;
};
class B : public A
{
public:
int func(A* p)
{
cout << p->a;
}
};
我真的不明白为什么我不能通过'p-> a'访问'a'。
无论如何在B级中访问p的成员'a'而不将'protected'更改为'public'?
在这个主题上,C ++ 03标准声明(强调我的):
11.5受保护的成员访问权限
1当派生类的朋友或成员函数引用受保护的非静态成员函数或受保护的基类的非静态数据成员时,除了前面第11章中描述的那些之外,还应用访问检查。除非形成指向成员的指针( 5.3.1), 访问必须通过指向,引用或派生类本身的对象 (或从该类派生的任何类)(5.2.5)。
但是,您在此处所做的是尝试通过指向基类的指针进行访问,这是非法的。 如果您将签名更改为
int func(B* p) // instead of A*
你会发现它现在正常编译。
这也是为什么你可以访问的原因a
从内无故障class B
:访问是通过隐含的指针,做出this
,这是一个类型的B*
(同样派生类)。 如果你试过这个:
A* parent = static_cast<A*>(this);
int x = parent->a; // Does not compile!
由于同样的原因,你会发现它不会编译。
反过来也适用:如果你将指针p
向下转换为B*
你可以正常访问protected
成员:
class A
{
public:
// Added virtual destructor so that the class acquires a vptr,
// making dynamic_cast possible.
virtual ~A() {};
protected:
int a;
};
class B : public A
{
public:
int func(A* p)
{
// Now if we downcast p to B* we can access a just fine
// Of course if p does not actually point to a B, the
// program will have undefined behavior
int x = dynamic_cast<B*>(p)->a;
}
};
使用p->a
只允许你访问A的公共变量。由于a
是受保护的变量,你应该使用cout << a
,因为a
是在B类中继承的。
我想你可以通过B级friend
使用cout << p->a
。
或者通过使用指向B
的指针而不是指向A
的指针,正如Jon指出的那样。
啊,这是一个很好的问题。 首先,让我先说B
不是A
的朋友,因此无法通过对象的“A”视图访问A
的私有(或受保护的)。 即使我们属于B
级的范围,我们也不能只是四处寻找A
的私人(或受保护的)。
然而,B 确实有a
。 它确实可以访问它,因为它被声明为A
的受保护成员。 但要看到的唯一方式int a
一个的内部B
,是从得到它B
对象的视图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.