c++ - 具有覆盖的嵌套类如何工作?

我想知道如何解释这一机制:

class Base{
  class Other;
  virtual void test() = 0;
};
class Other: Base{
  virtual void test() override;
};
void Other::test(){ /*do something*/}

看起来我有一个名为 Base 的基类。它包含一个继承自 Base 的嵌套类。所以如果我打电话:

Base obj;
obj.test(); <-- it trigers the test() function from the Other class, doesn't it?

给定的例子和下面的例子有什么区别:

class Base{
  virtual void test() = 0;
};
class Other: Base{
  virtual void test() override;
};
void Other::test(){ /*do something*/}

将 Other 类隐藏在 Base 类中有什么好处?

最佳答案

class Base{
  virtual void test() = 0;
};
Base obj;  // #0

#0 格式错误,因为 Baseabstract class ,因为它至少有一个纯抽象成员函数

Abstract class

Defines an abstract type which cannot be instantiated, but can be used as a base class.

A pure virtual function is a virtual function whose declarator has the following syntax:

declarator virt-specifier(optional) = 0   

[...] An abstract class is a class that either defines or inherits at least one function for which the final overrider is pure virtual.

当您从基指针或引用(对于特定运行时调用)引用派生对象分派(dispatch)到虚函数时,会发生对多态对象的动态分派(dispatch)。

在下面的例子中:

struct Base {
    virtual void test() const = 0;
};

struct A final : public Base {
    void test() const override {}; // #1   
};

struct B final : public Base {
    void test() const override {}; // #2   
};

void f(Base const& b) { 
    b.test();  // #3
}

#3 处对虚拟成员函数 test() 的调用可以分派(dispatch)给 A::test()B::test(),取决于函数 f 的参数。

f(A{});  // 'test()' call in 'f' dispatches to #1
f(B{});  // 'test()' call in 'f' dispatches to #2

what would be the benefit of hidding the Other class in the Base class?

在您的原始示例中,Base 类向自身声明了一个嵌套类(但未定义它),这意味着 Other 类在 Base 中声明的与派生自它的 Other 类不同。

  • 在类中声明嵌套类是一个完全与类继承层次结构正交的单独主题
  • 在基类之外的前向声明,它打算前向声明基类认为可能派生自它的派生类,这将是一种反模式,因为抽象(接口(interface))类的全部意义在于提供一个公共(public)客户端 API,可以由不同的派生类以多态方式使用。换句话说,基类通常永远(不需要)知道它的派生类(除了通过奇怪的重复出现的模板模式的静态多态性的特殊情况)。

https://stackoverflow.com/questions/66025120/

相关文章:

powershell - 如何在 Powershell 中对 3000 万条 csv 记录进行排序

java - 如果有 happens-before 保证,让 "this"在构造函数的最后一个语句中

swift - SwiftLint 的开关大小写格式问题

c# - 如何使用 C# 连接到 Azure 存储表

javascript - 使用路由器 "No overload matches this call"

flutter - 具有动态高度的动画容器 Flutter

c - 程序输出说明

c++ - 为什么 std::ranges::view_interface 使用 CRTP

list - 从列表中获取元素 Terraform

python - 将 seq2seq NLP 模型转换为 ONNX 格式会对其性能产生负面影响吗?