#include <iostream>
using namespace std;
class A
{
protected:
int a;
};
class B : public A
{
public:
int func(A* p)
{
cout << p->a;
}
};
我真的不明白为什么我不能通过'p-&gt; a'访问'a'。
有没有在B类中访问p的成员'a'而不将'protected'更改为'public'?
答案 0 :(得分:10)
在这个主题上,C ++ 03标准声明(强调我的):
11.5受保护的成员访问
1当朋友或成员的职能时 派生类引用受保护的非静态成员函数或 受保护的基类的非静态数据成员,访问检查 适用于前面条款中描述的那些 11.除非形成指向成员的指针(5.3.1),否则访问 必须通过指向,引用或派生的对象 class本身(或从该类派生的任何类)(5.2.5)。
但是,您在此处正在尝试通过指向 base 类的指针进行访问,这是非法的。如果您将签名更改为
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;
}
};
成员:
{{1}}
答案 1 :(得分:2)
使用p->a
只允许您访问A的公共变量。由于a
是受保护的变量,您应该使用{{1因为cout << a
是在B类中继承的。
我认为您可以a
使用cout << p->a
B类。
或者使用指向friend
的指针而不是指向B
的指针,如Jon所示。
答案 2 :(得分:1)
啊,这是一个很好的问题。首先,让我首先说B
不是A
的朋友,因此无法通过“{1}”的“A”视图访问A
的私有(或受保护的)物体。即使我们处于班级B
的范围内,我们也不能只看到A
的私有(或受保护的)。
但是, 有一个a
。它确实可以访问它,因为它被声明为A
的受保护成员。但是,在int a
内查看B
的唯一方法是从对象的B
视图中获取它。