标准如何支持在基类S中调用纯虚拟函数

How does the Standard support this call of a pure virtual function in the base class S?

本文关键字:调用 函数 虚拟 基类 何支持 支持 标准      更新时间:2023-10-16

考虑这个片段:

#include <iostream>
struct S {
    virtual void pure1() = 0;
    virtual void pure2() = 0;
};
struct T : S {
    void pure1() { std::cout << "T::pure1" << 'n'; }
    void pure2() { std::cout << "T::pure2" << 'n'; }
};

void S::pure2() { std::cout << "S::pure2" << 'n';}
int main()
{
    T t;
    t.S::pure2();
}

它打印S::pure2

看看C++11标准,我不知道这到底是怎么发生的。我认为这与§3.4.5/4:有关

如果类成员访问中的id表达式是的限定id表单

类名或命名空间名称::。。。

后面的类名或命名空间名称。or->运算符首先在对象表达式和名称的类中查找,如果已找到,正在使用。否则,它将在整个后缀表达式

但我不明白纯虚拟函数pure2()是如何在具有上述表达式t.S::pure2();的基类S中找到的。

在基类中实现纯虚拟函数是可以的。标准规定有效(强调矿):

10.4抽象类

2抽象类是一个只能用作其他类的基类的类;除了作为派生自抽象类的子对象之外,不能创建抽象类的任何对象。如果类至少有一个纯虚拟函数,则该类是抽象的。[注意:这样的函数可能是继承的:请参阅下文。--结束注释]通过在类定义中的函数声明中使用纯说明符(9.2),可以将虚拟函数指定为纯函数只有当使用限定id语法(5.1)调用或像使用(12.4)一样调用时,才需要定义纯虚拟函数。

如果你没有打电话给

t.S::pure2();

则可以省略S::pure2()的实现。如果你没有实现S::pure2(),但仍然调用,这将是一个链接时间错误

t.S::pure2();

您引用的位涵盖了表达式t.S::pure2()S的查找。它根本不适用于名称pure2

此处的相关裁决为10.3/15:

作用域运算符(5.1)的明确限定抑制了虚拟调用机制。示例:

class B { public: virtual void f(); };
class D : public B { public: void f(); };
void D::f() { /* ... */ B::f(); }

这里,D::f中的函数调用确实调用了B::f,而不是D::f-结束示例]