虚拟函数的行为类似于动态转换

Geo*_*rge 4 c++ rtti

Bjarne在《联合打击战斗机 C++ 编码标准》中指出:

仅允许通过以下机制之一进行向下转换(从基类转换为派生类):

  1. 虚拟函数的行为类似于动态转换(在相对简单的情况下最有可能有用)
  2. 使用访问者(或类似)模式(在复杂情况下最有可能有用)

我无法理解第一个提议。谷歌搜索没有给出任何例子,也没有解释。

虚函数如何像动态强制转换一样起作用?

Elj*_*jay 6

您可以使用虚函数进行向下转换,如下所示:

struct Bar;

struct Foo {
  virtual Bar* as_bar() { return nullptr; }
};

struct Bar : Foo {
  Bar* as_bar() override { return this; }
};
Run Code Online (Sandbox Code Playgroud)

实际中不常用。


Jer*_*fin 6

它指的是一种在 C++ 早期很常见的技术,之前dynamic_cast,RTTI等被添加到该语言之前。

基本思想是这样的:

class Derived1;
class Derived2;

class Base {
public:
    virtual Derived1 *toDerived1() const { return nullptr; }
    virtual Derived2 *toDerivde2() const { return nullptr; }
};

class Derived1 : public Base { 
public:
    Derived1 *toDerived1() const override { return this; }
    Derived2 *toDerived2() const override { return nullptr; }
};

class Derived2 : public Base { 
public:
    Derived1 *toDerived1() const override { return nullptr; }
    Derived2 *toDerived2() const overrode { return this; }
};
Run Code Online (Sandbox Code Playgroud)

这让你可以做一些类似于dynamic_cast指针上的操作,如果被指针对象实际上是该类型,则生成一个指向预期类型的​​指针,否则生成一个nullptr.

但这有明显的缺点。所涉及的每个类都必须了解其他所有类。添加新类意味着向每个类添加新功能。除非整个类结构是完全静态的(并且只有少量类),否则这很快就会变成维护噩梦。

参考

这一技术在《Effective C++》第 1 版第 39 条中有所介绍。我还没有进行确认,但它可能已从较新的版本中删除,因为(至少在大多数程序员看来)添加了 使其dynamic_cast过时(最好)。