带覆盖的嵌套类如何工作?
我想知道如何解释这种机制:
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*/}
在 Base 类中隐藏 Other 类有什么好处?
回答
class Base{ virtual void test() = 0; }; Base obj; // #0
#0是形成不良的作为Base是一个抽象类,因为它具有至少一个纯粹的抽象成员函数。
抽象类
定义一个不能被实例化但可以用作基类的抽象类型。
纯虚函数是其声明符具有以下语法的虚函数:
declarator virt-specifier(optional) = 0[...] 抽象类是定义或继承至少一个最终覆盖为纯 virtual 的函数的类
。
当您从基指针或引用分派到虚函数时,会发生多态对象的动态分派,该基指针或引用(对于特定的运行时调用)引用派生对象。
在以下示例中:
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
}
对虚成员函数test()at的调用#3可以分派给A::test()或B::test(),具体取决于函数的参数f。
f(A{}); // 'test()' call in 'f' dispatches to #1
f(B{}); // 'test()' call in 'f' dispatches to #2
在 Base 类中隐藏 Other 类有什么好处?
在您的原始示例中,Base该类向自身声明了一个嵌套类(但未定义它),这意味着在中Other声明Base的Other类与从它派生的类不同。
- 在类中声明嵌套类是一个独立的主题,与类继承层次结构完全正交
- 甲向前声明的是打算前进声明的派生类的基类自以为基类之外可以推导从这将是一个反模式,与抽象的(接口)整点的类是提供一种公共客户端API,它可以被不同的派生类多态使用。换句话说,基类通常永远不应该(不需要)知道它的派生类(除了通过奇怪的重复模板模式进行的静态多态的特殊情况)。