问题标签 [private-inheritance]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
559 浏览

c++ - 用私有基函数覆盖公共虚函数?

让我们考虑两个类AB具有以下接口:

然后是从两者继承的第三个类,A公开是因为它实现了这个“接口”,而B私下是因为那是实现细节。

但是,在这个特定的实现中,start()只需要包含对B::start(). 所以我想我可以使用快捷方式并执行以下操作:

并完成它,但显然它不起作用。所以我得到using私有基本功能无法覆盖虚拟。由此,有两个问题:

  • 有什么方法可以使这项工作像我认为的那样有效吗?
  • 为什么编译器会接受此代码为有效的?正如我所看到的,现在有两个start()函数具有完全相同的签名,C但编译器似乎很好,只调用A::start().

编辑:一些精度:

  • 目标是通过指针操作C对象。A
  • 我目前正在使用一个只调用的简单函数B::start(),我特别想知道 using 声明是否确实可以“覆盖”虚拟,如果不能,如何允许这两个函数共存。
  • 为了简单起见,我可能省略了一些东西,比如virtual继承。
0 投票
1 回答
327 浏览

c++ - 为什么 Visual Studio 编译器在此示例中允许违反私有继承?

我在 Visual Studio 2013 和 2017 中发现了非常奇怪的行为std::unique_ptr。让我们考虑一个例子:

请注意,继承是私有的。此示例仅在 Visual Studio 上编译。此外,虚函数调用之所以有效,是因为它是公共继承。所以我们有封装违规,因为从Derivedto的转换Base应该是不可访问的。谁能解释为什么 Visual Studio 允许这样做?这是一个已知问题吗?

下面的行由于合理的原因无法编译。第一种用法和第二种用法之间的唯一区别在于第二种用法,B即创建了命名对象。

它是否与这个仍未解决的问题有某种关系?

0 投票
4 回答
2275 浏览

c++ - 如何调用所有基类的复制构造函数以复制 C++ 中菱形继承中的大多数派生类对象?

考虑下面的代码:

程序的输出如下:

因此,对于 line类D d(d1)的复制构造函数D被调用。在继承过程中,我们需要显式调用基类的复制构造函数,否则只会调用基类的默认构造函数。到这里我才明白。

我的问题:

现在我想在D d(d1)执行期间调用所有基类的复制构造函数。为此,如果我在下面尝试 D(const D & obj) : A(obj), B(obj), C(obj) {cout << "8";} 然后我得到这个错误:错误:'class A A::A' is inaccessible within this context

如何解决问题。我想要 的复制构造函数AB以及C何时D调用的复制构造函数。这可能是很小的变化,但我没有得到。

0 投票
2 回答
395 浏览

c++ - 为什么在创建大多数派生类的对象时,大多数基类(虚拟)的默认构造函数没有在私有虚拟继承中被调用?

在创建大多数派生类的对象时,如何在私有虚拟继承中调用大多数基类的默认构造函数。但是当在大多数派生类的构造函数初始化列表中提到时,同样不会被调用。

我的问题:

对于下面提到的代码

我得到以下编译错误:

错误:在此上下文中无法访问“类 AA::A”

为什么 A() 构造函数在这里无法访问?

另一方面,下面提到的代码被成功编译并且 A() 构造函数被调用。

程序的输出是: 1234 意味着 A() 构造函数被调用。

那么,为什么在上述两种情况下调用构造函数 A() 的行为会发生变化?

我知道的:

(1) 当我对 B & C 进行“公共虚拟继承”时,即使在大多数派生类的构造函数初始化程序列表中提到了大多数基类的默认构造函数,也会被调用。表示下面的语句编译。D() : A(), B(), C() {cout << "4";}

(2) 在虚继承中,大多数派生类的构造函数直接调用虚基类的构造函数。

对我来说,这可能是虚拟继承的概念问题。请帮助我理解这一点并为此分享良好的参考资料。

0 投票
4 回答
303 浏览

c++ - “C++ 编程语言”中描述的私有继承用法

The C++ Programming Language , 4th Edition 的第 20.5.2 节“访问基类”(第 605 页)中,它说(关于私有继承):

当通过将接口限制为基类来定义类时,私有基类最有用,这样可以提供更强的保证。例如,B 是 Z 的实现细节。指针模板的向量从§ 25.3 就是一个很好的例子。

目前尚不清楚 Bjarne Stroustrup 在这里想说什么。如何通过将“接口”限制为基础来定义类?他所说的“更有力的保证”是什么意思?

0 投票
2 回答
188 浏览

c++ - 私有继承,返回对基类静态成员的引用

我有一个关于从私有继承基类的类继承的简单问题,即我们有

了解HeirsHeir无法访问 '其' 的任何内容Base。特别是,它不能有一个方法返回Base &对自身的引用。但是为什么它不能返回对另一个Base 对象的引用呢?那么为什么以下代码无法编译:

至少我的编译器(MinGW 5.3,即 Windows 的 gcc)给出了

据我了解,这没有意义,因为此时我没有调用 Base 的构造函数,而是返回一个引用(对 Base 实例)。

请注意,可以通过使用来修复错误

这肯定与 C++03 §11.2/3 相关联(参见 [ C++ 私有继承和静态成员/类型

注意:私有基类的成员可能无法作为继承的成员名称访问,但可以直接访问。

但我不明白为什么这是必要的。有人可以解释一下吗?

0 投票
3 回答
208 浏览

c++ - c++ 入门是否对`dynamic_cast`的使用有问题?

引自 C++ Primer 5th 19.2.1。dynamic_cast 运算符

dynamic_cast 具有以下形式:

其中 type 必须是类类型并且(通常)命名具有虚函数的类。在第一种情况下,e必须是一个有效的指针(第 2.3.2 节,第 52 页);第二,e 必须是左值;第三,e不能是左值。

在所有情况下,类型e必须是从目标类型公开派生的类类型、目标类型的公共基类或与目标类型相同。如果e具有这些类型之一,则转换将成功。否则,施法失败。
如果对指针类型的 dynamic_cast 失败,则结果为 0。如果对引用类型的 dynamic_cast 失败,则运算符抛出类型异常bad_cast

但是,在这里我写了一个代码片段:

在上面的代码片段中,A只是 的私有基数B,c++ 入门没有考虑到这一点。但是,此代码片段可以编译并运行而不会出现错误。入门有错吗?

0 投票
0 回答
347 浏览

c++ - 如何从 DOxygen 继承图中排除一个类?

我的项目中有一个模板化的 C++ 类,它仅用于调试目的——在正常构建中,它编译为一个空/无操作类。这个类被我的许多其他类私下继承。

就其目的而言,这很好用;问题是它使我的 DOxygen 生成的继承图非常混乱——在某些情况下,图中可见节点的数量几乎翻了一番。这个类是一个私有的实现细节,它在继承图中的存在并没有向图中添加任何有用的信息,只是很多混乱。

因此,我想从继承图中排除该类,以使它们一目了然。

我已经尝试过以下方法,但没有任何运气:

  1. 添加@cond HIDDEN_SYMBOLS@endcond围绕该类(在其头文件中)
  2. 将不需要的类的名称添加到EXCLUDE_SYMBOLS我的 .dox 文件的行中
  3. #ifndef DOXYGEN_SHOULD_IGNORE_THIS / #endif在其头文件中围绕类的声明添加了保护,并添加DOXYGEN_SHOULD_IGNORE_THISPREDEFINED我的 .dox 文件的行中。

上述所有努力只是使继承图中不需要的节点不可点击/变灰——但它们不会从图中隐藏/排除它们。

有没有办法只从继承图中删除类?(我不太关心 Doxygen 是否记录了这个类;我只是希望它从所有继承图中排除)

或者,如果做不到这一点,有没有办法从继承图中删除所有私有继承的超类?就我的目的而言,这可能“足够好”。

0 投票
3 回答
91 浏览

c++ - 如何在 C++ 中访问私有继承的类成员?

我试图理解私有继承的概念。

到目前为止,我所看到的所有地方都写道,私有继承使得派生类无法访问其成员。

这不是让它有点没用吗?如果我无法访问继承的类,那么首先派生的目的是什么?

现在我知道私人课程实际上是有用的并且很有帮助。我只是很难理解如何。

0 投票
1 回答
348 浏览

c++ - 在 C++ 中,是否可以将 CRTP 与私有基础一起使用?

在 C++ 中,我有许多与继承无关的类,它们定义了一个方法std::string get_name() const

许多类需要几个实用函数,它们是根据 get_name() 实现的。我希望实现 get_name() 的类也能获得这些实用函数。举一个愚蠢的例子,假设对于每个有 get_name 的类,我都想拥有void print_name() const { std::cout << get_name() << std::endl; }. 不过,有一些这样的功能,我不想在每个需要它们的类中重复它们。

听起来像是 CRTP 的工作:

效果很好。

这是皱纹 - 如果我希望 print_name() 在子类中是私有的怎么办?如果子类从 NameMethods 私有继承,则向下转换将不会编译(不可访问的基础)。我可以用 reinterpret_cast 替换它,一个简单的例子可以工作,但是如果有任何多重继承,reinterpret_cast 就不会做正确的事情,这在一般情况下可能存在。

有没有简单的方法来做这种事情?

谢谢!

编辑:我应该添加一点背景。我正在尝试以尽可能使用协议而不是抽象超类的风格编写。如果我使用公共 get_name() 和受保护的 print_name() 创建一个抽象超类,我可以轻松地让一切正常工作。问题是我不想要一个抽象超类。它会有几个我希望不相关的子类(因为我最终想使用 mixins 或 MI 组合它们)。

我的想法是我将组成一个具体的类,并且在该类或超类中的某个地方,某些东西将实现 get_name()。该具体类将需要一组实用函数,但这些实用函数不应该是接口的一部分。