这是我的代码 -

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

这给出了编译时间错误。

error: 'base' is an inaccessible base of 'derived'

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

有帮助吗?

解决方案

$ 11.2/4州 -

如果

  • B的发明公共成员将是N或
  • R发生在N类的成员或朋友中,B的发明公共成员将是N或受保护的成员
  • R发生在n类P类的成员或朋友中,B的发明公共成员将是P的私人或受保护成员,或
  • 存在S类,因此B是R和S可访问的S基类是可在R的N级的基类。”

这里的“ b”是“ base”,“ n”是“衍生”和“ r”是主要的。

  1. 考虑第二子弹 - r发生在n类的成员或朋友中,...'。本条款不适用,因为“ r”(main)既不是“ n”的成员,也不是朋友(派生)

  2. 考虑第三个子弹'r发生在P类的成员或朋友中。这个词也不适用于上述相同的原因

  3. 考虑第四个子弹 - 再次适用此条款

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

$ 11.2/5州 -

如果可以访问基类,则可以将指针隐式转换为派生类,以指向该基类的指针(4.10,4.11)。 [注意:X级的成员和朋友可以隐式将X*转换为X的私人或受保护的即时基类指针。— End Note

自从 Base 不是一个可访问的类 Derived 访问时 main, ,从派生类转换为基类的标准转换是不形成的。因此错误。

编辑2:

研究一些流行编译器的错误消息,这应该有助于您获得更好的理解。请注意,“无法访问”一词如何如此频繁,一致地弹出所有错误消息

参考文献来自标准N3000草案。我尚未下载最新的草稿:)

gcc prog.cpp:在函数'int main()':prog.cpp:27:错误:'base'是“派生”的无法访问的基础

Comeau Online“ ComeAutest.c”,第26行:错误:不允许转换为不可访问的基类“基础”。

VS2010错误C2243:'类型cast':从“派生 *”转换为“基础 *”,但不访问

其他提示

我怀疑问题是您无法将派生指针转换为基本指针,因为继承是私人的。

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

在C ++中,有3个访问级别指定符: public, protectedprivate. 。这些旨在确定谁可以访问方法,属性或基类。它在面向对象的语言中是典型的。

Here, you elected private 遗产。从概念上讲,这意味着您试图掩盖一个事实 Derived 继承 Base 对于局外人来说,这通常意味着这是一个实施细节。

结果,“外部”没有意识到这种关系。这是由编译器强制执行的 inaccessible 信息。

从设计的角度来看, private 通常不需要继承。 Liskov替代原则要么适用,您可以使用 public 继承,要么是实现细节,因此您使用构图。

你知道的 class derived 继承 class base, ,但是 main() 功能不知道。原因 main() 功能不知道是您制作的 class derived 私下继承 class base.

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

试试这个:

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

这给出了错误C2243:“类型cast':从“派生 *”到“ base *”的转换,但是无法访问该派生类已被私下继承。为了创建派生对象,首先调用将创建不发生的基类对象。 Soltuion是公开得出班级。无论您是否使用虚拟关键字与成员函数使用,这都不重要。

您需要在基类中声明您的SID()函数为虚拟。虚拟功能可以用派生类代替。否则,您可能会遇到编译器错误。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top