为什么derived*to base*之间的转换会因私有继承而失败?

Bru*_*uce 20 c++ private derived base accessible

这是我的代码 -

#include<iostream>
using namespace std;

class base
{
public:
    void sid()
    {
    }  
};

class derived : private base
{
public:
    void sid()
    {
    }
};

int main()
{
    base * ptr;
    ptr = new derived; // error: 'base' is an inaccessible base of 'derived'
    ptr->sid();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这给出了编译时错误.

error: 'base' is an inaccessible base of 'derived'
Run Code Online (Sandbox Code Playgroud)

由于编译器将尝试调用基类,sid()为什么我会收到此错误?有人可以解释一下.

Dou*_*der 35

我怀疑问题是你不能将派生指针转换为基指针,因为继承是私有的.

  • 真的不想花时间来解释Chubsdad的答案,这正是我需要知道的.在我的派生类定义中缺少`public`语句 (7认同)
  • 私有继承意味着您不希望基类接口可以访问除子类代码之外的其他代码. (2认同)

Chu*_*dad 16

$ 11.2/4状态 -

如果是,则可以在R处访问N的基类B.

  • B的发明公共成员将是N的公共成员,或
  • R发生在N类的成员或朋友中,B的发明公共成员将是N的私人或受保护成员,或者
  • R发生在从N派生的P类的成员或朋友中,B的发明公共成员将是P的私人或受保护成员,或者
  • 存在一个类S,使得B是在R处可访问的S的基类,S是在R处可访问的N的基类.

这里'B'是'Base','N'是'Derived','R'是main.

  1. 考虑第二个子弹 - 'R发生在N类的成员或朋友,......'.本条款不适用,因为'R'(主要)既不是'N'的成员也不是朋友(派生)

  2. 考虑第3个子弹 - 'R发生在P类的成员或朋友......中.本条款也不适用于与上述相同的理由

  3. 考虑第4个子弹 - 这个条款再次适用

因此,我们可以得出结论,"基础"不是"衍生"的可访问类.

$ 11.2/5州 -

如果可以访问基类,则可以隐式地将指向派生类的指针转换为指向该基类的指针(4.10,4.11).[注意:接下来,类X的成员和朋友可以隐式地将X*转换为指向X的私有或受保护的直接基类的指针.-end note]

由于Base访问Derived时不是可访问的类main,因此从Derived类到Base类的标准转换是不正确的.因此错误.

编辑2:

研究一些流行的编译器的错误消息,这应该有助于您更好地理解.请注意在所有错误消息中如何频繁且一致地弹出"不可访问"一词

参考文献来自标准草案N3000.我还没下载最新的草稿:)

GCC prog.cpp:在函数'int main()'中:prog.cpp:27:错误:'base'是'derived'的一个不可访问的基础

Comeau Online"ComeauTest.c",第26行:错误:转换为不可访问的基类"base"不允许ptr = new derived;

VS2010错误C2243:'type cast':从'derived*'到'base*'的转换存在,但是无法访问


Mat*_* M. 8

Chusbad提供了涉及标准的深入解释,我将尝试提供一个可访问的解释.

在C++中,有3个访问级别指示符:public,protectedprivate.这些意味着确定世卫组织可以访问方法,属性或基类.它是面向对象语言中的典型.

在这里,你选择了private继承.从概念上讲,这意味着您试图隐藏DerivedBase外部继承的事实,这通常意味着这是一个实现细节.

因此,"外部"并不知道这种关系.这是由编译器使用此inaccessible消息强制执行的.

从设计的角度来看,private通常不需要继承.Liskov替换原则适用并且您使用public继承,要么是实现细节,要么使用合成.


Win*_*mer 6

你知道class derived继承自class base,但main()函数不知道它.main()函数不知道它的原因是你class derived从中继承了PRIVATELY class base.

因此,当您尝试分配new derivedptr,指针类型不兼容.


ere*_*eOn 5

试试这个:

#include<iostream>
#include<conio.h>
using namespace std;

class base
{
      private:
      public:
          virtual void sid() // You might want to declare sid virtual
             {
                  cout<<"base";
             } 
          virtual ~base() // You then probably need a virtual destructor as well.
             {
             } 
};

class derived : public base //public inheritance
{
      private:
      public:
             void sid()
             {
                  cout<<"derived";
             }
};

int main()
{
    base * ptr;
    ptr = new derived;
    ptr->sid();
    getch();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)