15
#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
}

From what I understand, after def inherits privately from abc, protMember and publicMember become private in def. So, now when uvw inherits from def, it shouldn't have any data members. But we can weirdly access z.protMember from dummy_fn() , where as z shouldn't have a variable protMember in the first place. Am I going wrong anywhere?

4

3 回答 3

6

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

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

于 2013-11-08T08:26:55.740 回答
3

您不小心偶然发现了 C++ 被静态(而不是动态)类型化的结果;因此,访问检查是在编译时(而不是运行时)执行的,因此会推断变量的可见类型,而不是它的实际动态类型(这是运行时属性)。

解开这个例子:

class Base { protected: int prot; };

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

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

func是 的成员Derived,因此它可以访问 的所有数据成员Derived,既可以直接访问,也可以通过继承访问:

  • Derived直接继承自Base,所以Base可以访问
  • protis protectedin 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继承的事实,无法访问,因此,传递性,无法访问。BaseYetAnotherBaseBase::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 之类的动态语言进行对比,在这种语言中,对于类的对象,这将运行良好,MoreAttributeError对于没有a.

于 2013-11-08T09:59:07.360 回答
2

私有继承仅限制来自类外部的访问。它不限制派生类从基类看到的内容。因此,在您的情况下, wheredef私有继承自abcdef仍然可以访问所有受保护的abc. 只是客户def将无法访问来自abc; 甚至没有publicMember

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

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

这种说法是不正确的。 uvw就像拥有任何数据成员一样abcdef它们只是无法从外部访问。

有关详细信息,请参见此处:http: //www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/

于 2013-11-08T09:44:51.030 回答