继承:'A'是'B'无法访问的基础 [英] Inheritance: 'A' is an inaccessible base of 'B'

查看:105
本文介绍了继承:'A'是'B'无法访问的基础的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

$ cat inheritance.cpp 
#include <iostream>

using namespace std;

class A { };
class B : private A { };

int main() {
    A* ab = new B;
}
$
$ g++ inheritance.cpp
inheritance.cpp: In function 'int main()':
inheritance.cpp:9: error: 'A' is an inaccessible base of 'B'
$

我只是不明白这个错误。

I just do not understand this error.

据我所知,以及确认, private 继承只应改变 class B 成员的可见性对外界来说。

As I understand, and as this tutorial confirms, private inheritance should only change how the members of class B are visible to the outside world.

我认为私人说明人所做的不仅仅是改变 B类成员的可见度。

I think the private specifier is doing more than just change visibility of class B members here.


  • 我该怎么办这个错误是什么意思?

  • 基本上是什么问题在C ++中允许这种类型的代码?看起来完全无害。

推荐答案

通过将继承设为私有,你基本上就是这么说B继承自A(完全)的事实是私人的 - 外部世界无法访问/可见。

By making the inheritance private, you're basically saying that even the fact that B inherits from A (at all) is private -- not accessible/visible to the outside world.

没有进入冗长的讨论中如果被允许就会发生,简单的事实是它是不允许的。如果你想使用一个指向base的指针来引用派生类型的对象,那么你几乎完全坚持使用公共继承。

Without getting into a long-winded discussion of what would happen if it was allowed, the simple fact is that it's not allowed. If you want to use a pointer to base to refer to an object of derived type, then you're pretty much stuck with using public inheritance.

编辑:因为有人去了发送电子邮件以询问有关如果允许可能发生的情况的更多信息的麻烦,我想我会详细说明一下。

Since somebody went to the trouble of sending an email to ask for more information about what could happen if this was allowed, I guess I'll elaborate a little on it.

基本问题是私人继承必然是为了遵循 Liskov替代原则。公共继承声明派生对象可以替换基类的对象,并且仍然会产生正确的语义 。私有继承确实断言。私有继承所隐含的关系的通常描述是以来实现的。

The basic problem is that private inheritance is not necessarily intended to follow the Liskov substitution principle. Public inheritance asserts that a derived object can be substituted for an object of the base class, and proper semantics will still result. Private inheritance does not assert that though. The usual description of the relationship implied by private inheritance is "is implemented in terms of".

公共继承意味着派生类维护基类的所有功能并且可能增加更多。私有继承通常或多或少地相反:派生类使用通用基类来实现具有更受限制的接口的东西。

Public inheritance means a derived class maintains all the capabilities of the base class and potentially adds more besides. Private inheritance often means more or less the opposite: that the derived class uses a general base class to implement something with a more restricted interface.

仅举例来说,让我们假设为使用继承而不是模板实现C ++标准库中的容器的那一刻。在当前系统中, std :: deque std :: vector 是容器, std :: stack 是一个容器适配器,提供更受限制的接口。由于它基于模板,您可以使用 std :: stack 作为 std :: deque 的适配器或 std :: vector

Just for example, let's assume for the moment that the containers in the C++ standard library were implemented using inheritance rather than templates. In the current system, std::deque and std::vector are containers, and std::stack is a container adapter that provides a more restricted interface. Since it is based on templates, you can use std::stack as an adapter for either std::deque or std::vector.

如果我们想提供与继承基本相同的东西,我们可能会使用私有继承,所以 std :: stack 类似于:

If we wanted to provide essentially the same with inheritance, we would probably use private inheritance, so std::stack would be something like:

class stack : private vector {
    // ...
};

在这种情况下,我们肯定会希望用户能够操纵我们的堆栈就好像它是一个向量。这样做可能(并且可能会)违反堆栈的期望(例如,用户可以在中间插入/移除项目,而不是如预期的那样纯粹的堆栈方式)。我们基本上使用 vector 作为实现堆栈的便捷方式,但是如果(例如)我们更改了 stack的实现独立(不依赖基类)或以 std :: deque 重新实现它,我们想要影响任何客户端代码 - 对于客户端代码,这应该只是一个堆栈,而不是一些特殊的vector(或deque)。

In this case, we definitely do not want the user to be able to manipulate our stack as if it were a vector. Doing so could (and likely would) violate the expectations of a stack (e.g., the user could insert/remove items in the middle, rather than a purely stack-like fashion as intended). We're basically using vector as a convenient way to implement our stack, but if (for example) we changed the implementation for stack stand alone (with no dependence on a base class) or re-implement it in terms of std::deque, we do not want that to affect any client code -- to the client code, this is supposed to be just a stack, not some specialized variety of vector (or deque).

这篇关于继承:'A'是'B'无法访问的基础的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆