像动态转换一样的虚函数
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:
- Virtual functions that act like dynamic casts (most likely useful in
relatively simple cases)
- 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_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; }
};
这让你可以做一些类似于指针上的 dynamic_cast
的事情,如果指针对象实际上是那种类型,则产生指向预期类型的指针,否则产生 nullptr
。
虽然这有明显的缺点。所涉及的每个 class 都必须了解其他每个 class。添加一个新的 class 意味着为每个 class 添加一个新功能。除非整个 class 结构是完全静态的(并且总共有少量 classes),否则这很快就会变成维护噩梦。
参考
Effective C++,第 1 版,第 39 项中介绍了这项技术。我还没有检查确定,但它可能已从较新的版本中删除,因为(至少在大多数程序员看来)添加 dynamic_cast
使其过时(充其量)。
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:
- Virtual functions that act like dynamic casts (most likely useful in relatively simple cases)
- 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_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; }
};
这让你可以做一些类似于指针上的 dynamic_cast
的事情,如果指针对象实际上是那种类型,则产生指向预期类型的指针,否则产生 nullptr
。
虽然这有明显的缺点。所涉及的每个 class 都必须了解其他每个 class。添加一个新的 class 意味着为每个 class 添加一个新功能。除非整个 class 结构是完全静态的(并且总共有少量 classes),否则这很快就会变成维护噩梦。
参考
Effective C++,第 1 版,第 39 项中介绍了这项技术。我还没有检查确定,但它可能已从较新的版本中删除,因为(至少在大多数程序员看来)添加 dynamic_cast
使其过时(充其量)。