像动态转换一样的虚函数

Virtual functions that act like dynamic casts

Bjarne 在 JOINT STRIKE FIGHTER AIR VEHICLE C++ CODING STANDARDS 中指出:

Down casting (casting from base to derived class) shall only be allowed through one of the following mechanism:

  1. Virtual functions that act like dynamic casts (most likely useful in relatively simple cases)
  2. Use of the visitor (or similar) pattern (most likely useful in complicated cases)

我无法理解第一个命题。谷歌搜索没有提供示例,也没有解释。

虚函数如何像动态转换一样工作?

你可以像这样使用虚函数向下转型:

struct Bar;

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

struct Bar : Foo {
  Bar* as_bar() override { return this; }
};

实际上不经常使用。

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

基本思路是这样的:

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; }
};

这让你可以做一些类似于指针上的 dynamic_cast 的事情,如果指针对象实际上是那种类型,则产生指向预期类型的​​指针,否则产生 nullptr

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

参考

Effective C++,第 1 版,第 39 项中介绍了这项技术。我还没有检查确定,但它可能已从较新的版本中删除,因为(至少在大多数程序员看来)添加 dynamic_cast 使其过时(充其量)。