Effective C++ 规则41:了解隐式接口和编译期多态

1、隐式接口

C++ 中的 隐式接口 是指类或者模板中不显式声明为接口的一部分,但仍然可以像接口一样使用的成员或方法。隐式接口通常指那些不显式声明为虚函数的函数或者方法,但在多态上下文中仍然能表现出类似接口的行为。
隐式接口通常出现在模板编程中,尤其是 模板类型推导、SFINAE(Substitution Failure Is Not An Error) 技术或者 类型特性(type traits)等编译期机制中。它使得类和函数可以灵活地与多种类型协作,而无需显式继承或声明接口。考虑下面的例子:

// 隐式接口的示例:类的模板
template <typename T>
class Printer {
public:void print(const T& value) {value.print();  // 假设 T 类型有一个 print() 方法}
};

这里的 Printer 类依赖于类型 T 是否有 print() 方法。这并没有显式声明接口,但是如果类型 T 提供了 print() 方法,那么 Printer 就能使用它。这就是隐式接口的一个示例:Printer 并不直接约束 T 必须实现 print() 方法,但只要 T 提供了 print(),它就能在 Printer 中使用。

class A {
public:void print() const {std::cout << "Class A" << std::endl;}
};class B {
public:void print() const {std::cout << "Class B" << std::endl;}
};int main() {Printer<A> printerA;printerA.print(A());  // 输出 "Class A"Printer<B> printerB;printerB.print(B());  // 输出 "Class B"
}

这个例子中,A 和 B 类型并没有显式实现一个共同的接口或基类,但是 Printer 类可以接受这两个类型,并且调用它们的 print() 方法。这就是通过隐式接口实现的行为。

2、编译时多态

C++ 的 编译期多态(compile-time polymorphism)是指通过模板和编译期特性(如模板特化、SFINAE 等)在编译时进行的多态性选择。在编译期就根据类型特征来决定具体的行为,从而实现类似运行时多态的灵活性,但这种多态性是在编译时决定的。编译期多态最常见的实现方式是使用 模板特化 或 constexpr 函数。与运行时多态(基于虚函数)不同,编译期多态在编译时已经确定了所有类型和行为,因此非常高效,不需要运行时的动态派发开销。考虑下面的例子:

template <typename T>
void print_type(const T& value) {std::cout << "Unknown type" << std::endl;
}template <>
void print_type<int>(const int& value) {std::cout << "Integer: " << value << std::endl;
}template <>
void print_type<double>(const double& value) {std::cout << "Double: " << value << std::endl;
}int main() {print_type(42);         // 输出 "Integer: 42"print_type(3.14);       // 输出 "Double: 3.14"print_type("Hello");    // 输出 "Unknown type"
}

在这个例子中,print_type 函数通过模板特化实现了编译期的多态行为。虽然没有虚函数和继承,但编译器会根据传入的类型选择适当的特化版本。这种方法在编译时决定了调用哪个函数,效率很高。

3、编译期多态和类型特性

C++11 引入的 类型特性(type traits) 使得编译期多态变得更加灵活。类型特性允许你在编译时对类型进行检查,从而根据不同的类型执行不同的操作。例如,我们可以使用 std::is_integral 来检查类型是否为整数类型:

#include <iostream>
#include <type_traits>template <typename T>
void print_type(const T& value) {if (std::is_integral<T>::value) {std::cout << "Integer: " << value << std::endl;} else {std::cout << "Not an integer" << std::endl;}
}int main() {print_type(42);         // 输出 "Integer: 42"print_type(3.14);       // 输出 "Not an integer"
}

在这个例子中,std::is_integral::value 是一个编译时常量,决定了是否执行整数类型的逻辑。这就是编译期多态的一种形式,利用类型特性在编译阶段就选择不同的代码路径,而不是依赖运行时的动态类型。

4、隐式接口与编译期多态的关系

  • 隐式接口 允许我们在不显式声明接口的情况下,实现不同类型的多态行为。这使得我们的代码更加通用,可以与多种类型协作,而无需强制每个类型都实现某个显式的接口。
  • 编译期多态 通过模板编程和类型特性等机制在编译时选择不同的行为。这种选择是静态的,避免了运行时的性能开销,同时也让我们能够在编译时确定最合适的实现。

5、个人体会

读完规则41,我意识到,在 C++ 中,灵活的多态性不仅仅限于传统的基类与虚函数机制,还可以通过模板编程、类型特性等技术在编译时实现。隐式接口使得代码更加通用,编译期多态则通过静态选择提高了性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/5960.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络安全 | 入侵检测系统(IDS)与入侵防御系统(IPS):如何识别并阻止威胁

网络安全 | 入侵检测系统&#xff08;IDS&#xff09;与入侵防御系统&#xff08;IPS&#xff09;&#xff1a;如何识别并阻止威胁 一、前言二、入侵检测系统&#xff08;IDS&#xff09;2.1 IDS 的工作原理2.2 IDS 的技术类型2.3 IDS 的部署方式 三、入侵防御系统&#xff08;…

数学规划问题2 .有代码(非线性规划模型,最大最小化模型,多目标规划模型)

非线性规划模型 FIrst:转化为标准型 在matlab中求非线性规划的函数 练习题: 典型例题: 最大最小化模型 核心思想&#xff1a; matlab的模型求解 经典例题: 多目标规划模型 基本概念 求解思路: 模型构建步骤 经典例题: 非线性规划模型 非线性规划&#xff08;Nonl…

2025年最新深度学习环境搭建:Win11+ cuDNN + CUDA + Pytorch +深度学习环境配置保姆级教程

本文目录 一、查看驱动版本1.1 查看显卡驱动1.2 显卡驱动和CUDA对应版本1.3 Pytorch和Python对应的版本1.4 Pytorch和CUDA对应的版本 二、安装CUDA三、安装cuDANN四、安装pytorch五、验证是否安装成功 一、查看驱动版本 1.1 查看显卡驱动 输入命令nvidia-smi可以查看对应的驱…

Transformer详解:Attention机制原理

前言 Hello&#xff0c;大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者&#xff0c;本系列文章是作者参加DataWhale2025年1月份学习赛&#xff0c;旨在讲解Transformer模型的理论和实践。&#x1f632; 本文将详细探讨Attention机制的原理…

npm install 报错:Command failed: git checkout 2.2.0-c

[TOC](npm install 报错&#xff1a;Command failed: git checkout 2.2.0-c) npm install 报错&#xff1a;Command failed: git checkout 2.2.0-c export NODE_HOME/usr/local/node-v14.14.0-linux-x64 npm config set registry https://registry.npmmirror.com 使用如上环…

从对等通信到万维网:通信模型变迁与拥塞求解

Leonard Kleinrock&#xff1a;我很清楚用不了多久这些计算机就会有相互通信的需求&#xff0c;但如何协调处理这些分时系统概率性产生的分组(不同于电路交换)&#xff0c;却没有有效的方法&#xff0c;我有处理该问题的方法&#xff0c;因此对于我的博士研究&#xff0c;我决定…

【Vim Masterclass 笔记21】S09L39:Vim 设置与 vimrc 文件的用法示例(二)

文章目录 S09L39 Vim Settings and the Vimrc File - Part 21 Vim 的配色方案与 color 命令2 map 命令3 示例&#xff1a;用 map 命令快速生成 HTML 代码片段4 Vim 中的 Leader 键5 用 mkvimrc 命令自动生成配置文件 写在前面 本篇为 Vim 自定义配置的第二部分。当中的每个知识…

Debian 上安装PHP

1、安装软件源拓展工具 apt -y install software-properties-common apt-transport-https lsb-release ca-certificates 2、添加 Ondřej Sur 的 PHP PPA 源&#xff0c;需要按一次回车&#xff1a; add-apt-repository ppa:ondrej/php 3、更新软件源缓存&#xff1a; apt-g…

docker Ubuntu实战

目录 Ubuntu系统环境说明 一、如何安装docker 二、发布.netcore应用到docker中 Ubuntu系统环境说明 cat /etc/os-release PRETTY_NAME"Ubuntu 22.04.5 LTS" NAME"Ubuntu" VERSION_ID"22.04" VERSION"22.04.5 LTS (Jammy Jellyfish)&quo…

Android OpenGL(六) 纹理

纹理 纹理是一个2D图片&#xff08;甚至也有1D和3D的纹理&#xff09;&#xff0c; 它可以用来添加物体的细节&#xff1b;你可以想象纹理是一张绘有砖块的纸&#xff0c;无缝折叠贴合到你的3D的 房子上&#xff0c;这样你的房子看起来就像有砖墙外表了 纹理环绕方式 纹理坐…

C# 网络协议第三方库Protobuf的使用

为什么要使用二进制数据 通常我们写一个简单的网络通讯软件可能使用的最多的是字符串类型&#xff0c;比较简单&#xff0c;例如发送格式为(head)19|Msg:Heart|100,x,y,z…&#xff0c;在接收端会解析收到的socket数据。 这样通常是完全可行的&#xff0c;但是随着数据量变大&…

微软Win10 RP 19045.5435(KB5050081)预览版发布!

系统之家1月20日最新报道&#xff0c;微软面向Release Preview频道的Windows Insider项目成员&#xff0c;发布了适用于Windows10 22H2版本的KB5050081更新&#xff0c;更新后系统版本号将升至19045.5435。本次更新增加了对GB18030-2022标准的支持&#xff0c;同时新版日历将为…

零售业革命:改变行业的顶级物联网用例

mpro5 产品负责人Ruby Whipp表示&#xff0c;技术进步持续重塑零售业&#xff0c;其中物联网&#xff08;IoT&#xff09;正引领这一变革潮流。 研究表明&#xff0c;零售商们正在采用物联网解决方案&#xff0c;以提升运营效率并改善顾客体验。这些技术能够监控运营的各个方面…

ASP .NET Core 学习(.NET9)部署(一)windows

在windows部署 ASP .NET Core 的时候IIS是不二选择 一、IIS安装 不论是在window7 、w10还是Windows Server&#xff0c;都是十分简单的&#xff0c;下面以Windows10为例 打开控制面版—程序—启用或关闭Windows功能 勾选图中的两项&#xff0c;其中的子项看需求自行勾选&am…

【组件库】使用Vue2+AntV X6+ElementUI 实现拖拽配置自定义vue节点

先来看看实现效果&#xff1a; 【组件库】使用 AntV X6 ElementUI 实现拖拽配置自定义 Vue 节点 在现代前端开发中&#xff0c;流程图和可视化编辑器的需求日益增加。AntV X6 是一个强大的图形化框架&#xff0c;支持丰富的图形操作和自定义功能。结合 ElementUI&#xff0c;…

docker 部署confluence

1.安装docker的过程就不说了。 2.下载镜像。 docker pull cptactionhank/atlassian-confluence:7.4.0 docker images 3.下载pojie 包。 https://download.csdn.net/download/liudongyang123/90285042https://download.csdn.net/download/liudongyang123/90285042https://do…

C++ 二叉搜索树

目录 概念 性能分析 二叉搜索树的插入 二叉树的查找 二叉树的前序遍历 二叉搜索树的删除&#xff08;重点&#xff09; 完整代码 key与value的使用 概念 对于一个二叉搜索树 若它的左子树不为空&#xff0c;则左子树上所有的节点的值都小于等于根节点的值若它的右子树不为空…

重生之我在异世界学编程之C语言:深入指针篇(上)

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文&#xff08;1&#xff09;内置数…

HTTP 配置与应用(不同网段)

想做一个自己学习的有关的csdn账号&#xff0c;努力奋斗......会更新我计算机网络实验课程的所有内容&#xff0c;还有其他的学习知识^_^&#xff0c;为自己巩固一下所学知识&#xff0c;下次更新校园网设计。 我是一个萌新小白&#xff0c;有误地方请大家指正&#xff0c;谢谢…

YOLOv5训练自己的数据及rknn部署

YOLOv5训练自己的数据及rknn部署 一、下载源码二、准备自己的数据集2.1 标注图像2.2 数据集结构 三、配置YOLOv5训练3.1 修改配置文件3.2 模型选择 四、训练五、测试六、部署6.1 pt转onnx6.2 onnx转rknn 七、常见错误7.1 训练过程中的错误7.1.1 cuda: out of memory7.1.2 train…