多级私有和公共继承 - 异常访问

时间:2013-11-08 08:21:10

标签: c++ inheritance

#include<iostream>
using namespace std;
class uvw;
class abc{
   private:
      int privateMember;
   protected:
    int protMember;
   public:
    int publicMember;
};

class def : private abc{
    public:
       void dummy_fn();
};

class uvw: public def{

};

void def::dummy_fn()
{
   abc x;
   def y;
   uvw z;
   cout << z.protMember << endl; // This can be accessed and doesn't give a compile-error
}

根据我的理解,def私下从abc继承后,protMemberpublicMemberdef中变为私有。所以,现在当uvw继承自def时,它不应该有任何数据成员。但我们可以从z.protMember奇怪地访问dummy_fn(),其中z首先不应该有变量protMember。我在哪里出错了?

3 个答案:

答案 0 :(得分:6)

如果您尝试从免费功能访问它,它将无法正常工作。它在这种情况下有效,因为dummy_fn()def的成员函数,因此它可以访问def内的所有私有内容。由于z 是-a def,因此它也可以访问def个实例中的私有z成员。

或者至少这是我的猜测。这是一个奇怪的案例。

答案 1 :(得分:3)

你偶然发现了C ++静态(而不是动态)输入的后果;因此,访问检查在编译时(而不是运行时)执行,从而推断变量的可见类型,而不是实际动态类型(这是一个运行时属性)。

解开一点例子:

class Base { protected: int prot; };

class Derived: private Base { void func(); };

void Derived::func() { std::cout << prot << std::endl; }

funcDerived的成员,因此它可以访问Derived的所有数据成员,包括直接和可通过继承访问:

  • Derived直接从Base继承,因此可以访问Base
  • protprotected中为Base,因此任何可以访问prot的儿童都可以访问Base

因此,prot可以访问Derived(因此在Derived::func中)。


让我们展示访问路径的重要性:

class Another: private Base {};

class YetAnother: public Another { void func(); };

void YetAnother::func() { std::cout << prot << std::endl; } // ERROR (access)

此处,即使Base::prot中可以访问Another,因为Another隐藏了从Base继承到其他所有人的事实,YetAnother无法访问Base {1}}因此,传递上,无法访问Base::prot


让我们展示静态类型的效果:

class Basic { void func(); };

class More: public Basic { public: int a; };

void Basic::func() { std::cout << a << std::endl; } // ERROR (unknown)

在这里,即使More对象有a成员,但在编译Basic时,我们只能依赖Basic知道的内容。 Basic不知道a

将此与Python等动态语言进行对比,对于没有More的人来说,这对于类AttributeError的对象运行正常并且失败(a异常)。

答案 2 :(得分:2)

私有继承仅限制来自类外部的访问。它不限制派生类从基类中看到的内容。因此,在def abc私密地从def继承的情况下,abc仍然可以访问def的所有受保护成员。只有abc的客户才能访问publicMember中的任何内容;甚至不是uvw

另外,不要将私有继承与不继承成员或其他内容混淆。

  

所以,现在当uvw从def继承时,它不应该有任何数据成员。

这种说法不正确。 abc同样拥有def和{{1}}所拥有的任何数据成员,只能从外部访问它们。

参见例如详情请见http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/