C++中的四种多态 (The Four Polymorphisms in C++翻译) 您所在的位置:网站首页 面向对象实现英文 C++中的四种多态 (The Four Polymorphisms in C++翻译)

C++中的四种多态 (The Four Polymorphisms in C++翻译)

2024-07-11 22:03| 来源: 网络整理| 查看: 265

本文为The Four Polymorphisms in C++这篇文章的翻译,非机器翻译,如有理解或术语错误望指正,谢谢~

C++中的四种多态(Polymorphisms)

当人们在谈论C++的多态的时候,他们通常指的是通过基类的指针或者引用,来使用派生类,这其实被称为子类型多态(subtype polymorphism),但是他们经常会忘掉其实C++里面还有各种其他的多态,比如参数多态(parametric polymorphism),重载多态(ad-hoc polymorphism)和强制多态(coercion polymorphism)。

这些多态在C++中也有其他不同的名称:

子类型多态也被称为运行时多态(runtime polymorphism)。参数多态也被称为编译时多态(compile-time polymorphism)。重载多态也被称为重载(overloading)。强制多态也被称为**(显式的或隐式的)类型转换(casting)**。

我将在这篇文章里通过例子来说明C++中的所有多态,并告诉你为什么它们有这样的名字。

子类型多态(运行时多态)

子类型多态是人们在说C++多态时所能理解的那种,它可以通过基类的指针或者引用来使用派生类。

举个例子,假设你有各种的猫科动物, 在这里插入图片描述由于他们都属于猫科生物家族,所以他们都可以发出类似喵的叫声(原文是they all should be able to meow),这样他们都可以通过继承猫科动物Felid这个基类来表示,并重写meow这个纯虚函数。

// file cats.h class Felid { public: virtual void meow() = 0; }; class Cat : public Felid { public: void meow() { std::cout std::cout std::cout Cat cat; Tiger tiger; Ocelot ocelot; do_meowing(&cat); do_meowing(&tiger); do_meowing(&ocelot); }

主程序向do_meowing这个函数传递了指向cat, tiger和ocelot的指针,而这个函数期望一个指向Felid对象的指针。因为cat, tiger和ocelot都属于Felid,程序可以为每个猫科动物调用正确的meow函数,并且输出如下:

Meowing like a regular cat! meow! Meowing like a tiger! MREOWWW! Meowing like an ocelot! mews!

子类型多态也被叫作运行时多态,因为,多态函数调用的解析发生在运行时,并通过虚表间接完成。另一种解释方式是,编译器不能在编译期定位函数被调用的地址,而在程序运行时,通过取消引用虚表的右指针来调用函数。

在类型理论中这也被成为包含多态性。

参数多态(编译时多态)

参数多态提供了一种可以对任何类型数据执行相同代码的方法。在C++里,参数多态通过模板(template)来实现。

一个最简单的例子就是max函数,它用来寻找传入的两个参数的最大值,

#include #include template T max(T a, T b) { return a > b ? a : b; } int main() { std::cout std::string result(a); result += b; return result; } int main() { std::cout int foo; public: A(int ffoo) : foo(ffoo) {} void giggidy() { std::cout moo(55); // prints 55 // 译者注:传进去了55数字,但是隐式地调用了A类的构造函数,发生了int-> A的类型转换 }

如果你显示调用了A的构造函数,那就不会发生强制多态了,显示的调用类的构造函数总是比较好的,可以避免意外的转换。

此外,如果一个类定义了对类型T的转换操作符,那么这个类的对象可以用在任何需要使用类型T的地方。

比如,

class CrazyInt { int v; public: CrazyInt(int i) : v(i) {} operator int() const { return v; } // conversion from CrazyInt to int };

CrazyInt定义了转换为int类型的转换操作符,如果你有一个函数,比如print_int,需要传入一个int的参数,我们也可以直接把CrazyInt类型的对象传进去,

#include void print_int(int a) { std::cout


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有