C ++简单继承问题

时间:2011-09-12 15:20:31

标签: c++ class inheritance

#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'?

3 个答案:

答案 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视图中获取它。