当前位置: 首页 > news >正文

《Effective C++中文版,第三版》读书笔记7

条款41: 了解隐式接口和编译期多态

隐式接口:

​ 仅仅由一组有效表达式构成,表达式自身可能看起来很复杂,但它们要求的约束条件一般而言相当直接而明确。

显式接口:

​ 通常由函数的签名式(也就是函数名称、参数类型、返回类型)构成

​ 在源码中明确可见。

#include <iostream>// 个人感觉隐式和显式接口只是站在了不同的角度看一个类的接口。
// 站在类的角度:
// 类中定义的接口是显示的// 站在template 参数的这个角色的角度而言:接口是隐式的,就是个表达式。
// (换个说法:这个隐式接口其实就是隐藏条件的说法,如果某个类想要作为template的参数,它必须有满足template 表达式要求的接口)
class Base
{public:~Base() = default;virtual void myPrint() = 0;int size() {return 111;}
};class Derived: public Base
{public:Derived() {}~Derived() = default;virtual void myPrint(){std::cout << "Derived cout!!!" <<std::endl;}
};void myPrint1(Derived &dd)
{dd.myPrint();
}template<typename T>
void myPrint2(T t)
{t.myPrint();t.size();
}int main(int argc, char const *argv[])
{Derived dd;myPrint1(dd);myPrint2(dd);return 0;
}

编译期多态:

在编译时才能确定具体调用哪个函数

#include <iostream>
#include <string>// 编译期多态,个人理解就是:在编译时存在多个选择,根据参数类型的不同调用不同的函数。
// 对于重载: 在编译时根据参数的不同,选择不同的函数。(这些个函数已经存在,选一个心仪的)
// 对于function templates: 在编译期,根据不同的template参数具现出不同的函数(函数还没有,根据参数不同,现生成一个心仪的)
template <typename T>
T max1(const T &a, const T &b)
{return a > b ? a : b;
}int min1(const int &a, const int &b)
{std::cout << "int min" << std::endl;return a < b ? a : b;
}std::string min1(const std::string &a, const std::string &b)
{std::cout << "string min" << std::endl;return a < b ? a : b;
}int main(int argc, char const *argv[])
{int a = 11, b = 12;std::string a1("hello world"), b1("hello");std::cout << max1(a, b) << std::endl;std::cout << max1(a1, b1) << std::endl;std::cout << min1(a, b) << std::endl;std::cout << min1(a1, b1) << std::endl;return 0;
}

运行期多态:

在运行时才知道待用哪个函数。

#include <iostream>// 运行时多态演示代码
class Base
{public:~Base() = default;virtual void myPrint() = 0;
};class Derived: public Base
{public:Derived() {}~Derived() = default;virtual void myPrint(){std::cout << "Derived cout!!!" <<std::endl;}
};int main(int argc, char const *argv[])
{Base *pb = new Derived;// 程序运行的时候,才能明确调用的时Derived的myPrint()pb->myPrint();delete pb;return 0;
}

请记住:

classes 和template都支持接口和多态

对于classes而言接口是显式的,以函数签名为中心。多态则是通过virtual函数发生于运行期

对于template参数而言,接口是隐式的,基于有效表达式。多态则是通过template具现化和函数重载解析发生于编译器

条款42:了解typename的双重意义

请记住:

声明template参数时,前缀关键字class和typename可互换

请使用关键字表示嵌套从属类型名称;但不得在base class lists(基类列)或member initialization list(成员初值列)内以它作为base class修饰符。

条款43: 学习处理模板化基类内的名称

请记住:

​ 可在derived class templates内通过“this->”指涉base class templates内的成员名称,或藉由一个明白写出的“base class 资格修饰符”完成

写一段:

#include <iostream>
#include <string>
class CompanyA
{
public:CompanyA() {}~CompanyA() = default;void sendClearText(const std::string &msg){std::cout << "company A sendEncrypted msg = " + msg << std::endl;}void sendEncrypted(const std::string &msg){std::cout << "company A sendEncrypted msg = " + msg << std::endl;}
};class CompanyB
{
public:CompanyB() {}~CompanyB() = default;void sendClearText(const std::string &msg){std::cout << "company B sendEncrypted msg = " + msg << std::endl;}void sendEncrypted(const std::string &msg){std::cout << "company B sendEncrypted msg = " + msg << std::endl;}
};class MsgInfo
{
public:MsgInfo(const std::string &inmsg) : msg(inmsg) {}~MsgInfo() = default;std::string getMsg() const{return msg;}private:std::string msg;
};template <typename Company>
class MsgSender
{
public:MsgSender() {}~MsgSender() = default;void sendClear(const MsgInfo &info){std::string msg = info.getMsg();Company c;c.sendClearText(msg);}void sendSecret(const MsgInfo &info){std::string msg = info.getMsg();Company c;c.sendEncrypted(msg);}
};// 以template为基类定义子类
template <typename Company>
class LoggingMsgSender : public MsgSender<Company>
{
public:LoggingMsgSender() {}~LoggingMsgSender() = default;// 解决方案3:使用using声明式,假设sendClear在基类// using MsgSender<Company>::sendClear;void sendClearMsg(const MsgInfo &info){std::cout << "adasd" << std::endl;// g++报错: there are no arguments to 'sendClear' that depend on a template parameter,// so a declaration of 'sendClear' must be available// 解决方案1:使用编译参数:“-fpermissive”,使用该参数后从报错变成了告警。// 解决方案2:使用this// this->sendClear(info);sendClear(info); //LoggingMsgSender在被实例化之前不知道sendClear在哪里。编译器也不会到base classes内查找。// 解决方案4: 明确指出被调用函数位于基类中(这个方案不推荐使用),如果sendClear是一个virtual,这样会关闭“virtual 绑定行为”// MsgSender<Company>::sendClear(info);std::cout << "adasdfffff" << std::endl;}
};class CompanyZ
{
public:CompanyZ() {}~CompanyZ() = default;void sendEncrypted(const std::string &msg){std::cout << "company Z sendEncrypted msg = " + msg << std::endl;}
};// template<>这个不是template也不是标准class,而是个特化版的MsgSender template,在template实参是CompanyZ时候使用。
// 这就是模板全特化
template <>
class MsgSender<CompanyZ>
{
public:MsgSender() {}~MsgSender() = default;void sendSecret(const MsgInfo &info){std::string msg = info.getMsg();CompanyZ c;c.sendEncrypted(msg);}
};int main(int argc, char const *argv[])
{LoggingMsgSender<CompanyA> mca;mca.sendClear(std::string("hello"));mca.sendSecret(std::string("hello"));LoggingMsgSender<CompanyB> mcb;mcb.sendClear(std::string("hello"));mcb.sendSecret(std::string("hello"));// 模板全特化:针对某一个类型的全面特化。LoggingMsgSender<CompanyZ> mcz;// 特化版的MsgSender template中没有提供sendClear// mcz.sendClear(std::string("hello")); // 编译报错mcz.sendSecret(std::string("world"));return 0;
}

条款44: 将与参数无关的代码抽离templates

请记住:

​ template生成多个 classes和多个函数,所以任何template代码都不应该于某个造成膨胀的template参数产生相依关系。

​ 因非模板参数而造成的代码膨胀,往往可以消除。做法是以函数参数或class成员变量替换template参数。

​ 因类型参数(type parameters)造成的代码膨胀,往往可以降低,做法是让带有完全相同二进制表述的具象类型实现共享代码。

条款45:运用成员模板函数接受所有兼容类型

请记住:

​ 请使用member function templates 生成“可接受所有兼容类型”的函数

​ 如果你声明member templates 用于“泛化构造”或“泛化assignment”,你还需要声明正常的copy构造函数和copy assignment函数。

条款46:需要类型转换时请为模板定义非成员函数

请记住:

​ 当我们编写一个class template,而它所提供的“与此template相关”函数支持“所有参数之隐式转换”时,请将那些函数定义为“class template内部的friend函数”。

条款47:请使用traits class 表现类型信息

请记住:

​ Traits classes使得“类型相关信息”在编译期可用。它们以templates和“”完成实现

​ 整合重载技术后,traits classes有可能在编译期对类型执行if…else测试。

条款48:认识template元编程

这个可能太高阶了,目前知道有这么个东西就行。光靠这里去理解可能有点难。

什么是模板元编程(Template metaprogramming- TMP)?

编写template-base C++程序并执行于编译期的过程

TMP是被发现而不是发明出来的。

使用TMP的好处?

1.它让事情更容易

2.某些错误可以在编译期就找出来

3.可能在每一个方面都高效:较小的可执行文件、较短的运行期、较少的内存需求

缺点:

​ 编译时间变长了

难点:

​ 语法不直观,支持工具不充分。

请记住:

​ TMP可将工作由运行期迁移到编译期,从而实现早期错误侦测和更高的执行效率

​ TMP可被用来生成“基于政策选择组合”(based on combinations of policy choices)的客户定制代码,也可用来避免生成对某些特殊类型并不适合的代码。

相关文章:

《Effective C++中文版,第三版》读书笔记7

条款41&#xff1a; 了解隐式接口和编译期多态 隐式接口&#xff1a; ​ 仅仅由一组有效表达式构成&#xff0c;表达式自身可能看起来很复杂&#xff0c;但它们要求的约束条件一般而言相当直接而明确。 显式接口&#xff1a; ​ 通常由函数的签名式&#xff08;也就是函数名…...

脚本:python实现动态爱心

文章目录 效果代码Reference python实现dynamic heart 效果 代码 import turtle as tu import random as ratu.setup(0.5, 0.5) # 设置画板大小&#xff08;小数表示比例&#xff0c;整数表示大小&#xff09; tu.screensize(1.0, 1.0) # 设置屏幕大小 tu.bgcolor(black) #…...

【李宏毅】深度学习6:机器学习任务攻略

如果在测试集上的效果不佳&#xff0c;应该要做什么&#xff1f;Optimization 如何选择&#xff1f;解决 overfitting 的方法&#xff1f; 测试集上的效果不佳 看训练数据的loss&#xff0c;是不是模型本身就没训练好&#xff1f; 问题&#xff1a;model 太简单了&#xff0c…...

如何使用SQL SERVER的OpenQuery

如何使用SQL SERVER的OpenQuery 一、OpenQuery使用说明二、 OpenQuery语法2.1 参数说明2.2注解 三、示例3.1 执行 SELECT 传递查询3.2 执行 UPDATE 传递查询3.3 执行 INSERT传递查询3.4 执行 DELETE 传递查询 一、OpenQuery使用说明 在指定的链接服务器上执行指定的传递查询。 …...

element-tree树结构-默认选中第一个节点高亮-根据id选中节点高亮

前言 tree树结构是在开发中经常使用的组件&#xff0c;比如区域树&#xff0c;楼层树&#xff0c;组织架构树&#xff0c;等等包含节点关系 实际开发可能需要我们一进到页面选中树形结构第一个节点&#xff0c;并且调用数据&#xff0c;来达到用户体验 在用户选择之后&#x…...

Python实操 PDF自动识别并提取Excel文件

最近几天&#xff0c;paddleOCR开发了新的功能&#xff0c;通过将图片中的表格提取出来&#xff0c;效果还不错&#xff0c;今天&#xff0c;作者按照步骤测试了一波。 首先&#xff0c;讲下这个工具是干什么用的&#xff1a;它的功能主要是针对一张完整的PDF图片&#xff0c;可…...

JVM监控和调优常用命令jps|jstat|jinfo|jmap|jhat|jstack实战

1.JVM监控和调优的主要目的 性能优化:通过JVM调优,可以提高Java应用程序的性能,减少响应时间,提高吞吐量,以更好地满足用户需求。性能优化可以加快应用程序的执行速度,减少延迟,提高用户体验。 内存管理:JVM负责管理Java应用程序的内存。正确的内存管理可以避免内存泄漏…...

chatglm2-6b在P40上做LORA微调 | 京东云技术团队

背景&#xff1a; 目前&#xff0c;大模型的技术应用已经遍地开花。最快的应用方式无非是利用自有垂直领域的数据进行模型微调。chatglm2-6b在国内开源的大模型上&#xff0c;效果比较突出。本文章分享的内容是用chatglm2-6b模型在集团EA的P40机器上进行垂直领域的LORA微调。 …...

WebGL 同时使用多幅纹理

目录 前言 ​编辑 示例代码 颜色矢量的分量乘法来计算两个纹素最终的片元颜色 注册事件响应函数&#xff1a;loadTexture&#xff08;&#xff09;&#xff0c;最后一个参数是纹理单元编号。 请求浏览器加载图像&#xff1a; 配置纹理&#xff1a;loadTexture&#xff0…...

探索云计算和大数据分析的崛起:API行业的机遇与挑战【电商大数据与电商API接入】

I. 引言 随着云计算和大数据分析技术的快速发展&#xff0c;企业和个人对数据分析和处理的需求不断增加。在这个信息爆炸的时代&#xff0c;数据已成为企业决策和战略规划的重要基础。云计算提供了强大的计算和存储能力&#xff0c;使得大规模数据的处理和分析变得更加容易和高…...

android studio通过wifi、无线连接设备

AndroidStudio无线wifi调试设备_android studio wifi_zwylovemzj的博客-CSDN博客 使用​​adbWireless​​工具&#xff0c;其能够让手机用无线来取代USB连接而使用ADB工具 1. 手机需要与电脑在同一局域网内 2. 把adbWireless安装到手机上&#xff0c;并开启&#xff0c;上面…...

kafka 3.5 主题分区ISR伸缩源码

ISR(In-sync Replicas)&#xff1a;保持同步的副本 OSR(Outof-sync Replicas)&#xff1a;不同步的副本。最开始所有的副本都在ISR中&#xff0c;在kafka工作的过程中&#xff0c;如果某个副本同步速度慢于replica.lag.time.max.ms指定的阈值&#xff0c;则被踢出ISR存入OSR&am…...

1-centOS7搭建伪分布式

前言&#xff1a;虚拟机快照的使用 VMware Workstation 软件可以用快照进行迅速的虚拟机状态的切换 ※. 类似于虚拟机备份&#xff0c; 可以使用备份进行快速恢复。 比如没安装jdk之前拍摄快照来备份 ※. 若jdk没安装好或者jdk环境变量配置的有问题&#xff0c; 可以用安装之…...

对开源自动化测试平台MeterSphere的使用感触

1&#xff1a;该平台可以通过接口&#xff0c;参数&#xff0c;配置的维护&#xff0c;然后继续接口自动化“一键测试”&#xff0c;功能还是挺强大的&#xff0c;具体的使用需要研究 MeterSphere的官网&#xff1a;MeterSphere - 专业测试云 2&#xff1a;一键测试在生产环境…...

Spring boot 第一个程序

新建工程 选择spring-boot版本 右键创建类TestController&#xff1a; 代码如下&#xff1a; package com.example.demo; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springf…...

【SpringMVC】实现增删改查(附源码)

目录 引言 一、前期准备 1.1.搭建Maven环境 1.2.导入pom.xml依赖 1.3.导入配置文件 ①jdbc.properties ②generatorConfig.xml ③log4j2.xml ④spring-mybatis.xml ⑤spring-context.xml ⑥spring-mvc.xml ⑦修改web.xml文件 二、逆向生成增删改查 2.1.导入相关u…...

理财是什么?怎样学习理财?

大家好&#xff0c;我是财富智星&#xff0c;今天跟大家分享一下理财是什么&#xff1f;怎样学习理财的方法。 一、理财的基本原则 1、理财应注重投资而不是投机&#xff0c;要与时间为友。 让我们先考虑以下问题&#xff1a;什么样的回报才算是真正的高回报&#xff1f;假设有…...

华为云云耀云服务器L实例评测 | 开启OPC UA之旅

OPC Unified Architecture (OPC UA)是一种用于工业自动化的M2M协议(Machine-to-machine)&#xff0c;具有平台独立性&#xff0c;在Windows和Linux上都可以运行。随着云服务在工业现场的不断普及&#xff0c;OPCUA服务也开始大量部署在云端。 本文以华为云云耀云服务器L为基础…...

帝国CMS灵动标签如何调用$ecms_hashur[‘ehref‘]函数

我们在二次开发时,后台调用链接就需要加上帝国CMS的$ecms_hashur[ehref]函数,这是帝国CMS后台的安全函数,防止外部直接访问后台页面,直接强制访问后台链接就会提示“非法来源”。 我的站长站分享下制作自定义php页面,用帝国CMS灵动标签如何调用$ecms_hashur[ehref]函数方…...

ES6 拓展(下)

一、函数的拓展 1.1、默认参数 在ES5中设置默认参数&#xff1a; function func(words, name) {name name || "闷墩儿";console.log(words, name); } func("大家好&#xff01;我是"); func("大家好&#xff01;我是", "憨憨");func(…...

TouchGFX之自定义触发条件和操作

通过TouchGFX Designer&#xff0c;您可以自己定义具有触发条件和操作的交互组件。 自定义容器创建自定义触发条件&#xff1a;通过自定义容器的属性选项卡添加自定义触发条件 使用交互系统发送自定义触发条件&#xff1a; 通过自定义容器的“交互”选项卡&#xff0c;创建新的…...

Linux防火墙(iptables)

一、linux的防火墙组成 linux的防火墙由netfilter和iptables组成。用户空间的iptables制定防火墙规则&#xff0c;内核空间的netfilter实现防火墙功能。 netfilter&#xff08;内核空间&#xff09;位于Linux内核中的包过滤防火墙功能体系&#xff0c;称为Linux防火墙的“内核…...

zookeeper教程

zookeeper教程 zookeeper简介zookeeper的特点及数据模型zookeeper下载安装zookeeper客户端命令zookeeper配置文件zookeeper服务器常用命令zookeeper可视化管理工具zkuizookeeper集群环境搭建zookeeper选举机制使用Java原生api操作zookeeper使用java zkclient库操作zookeeper使用…...

杭州快递物流展-2024长三角快递物流供应链与技术装备展览会(杭州)

2024快递物流创新高质量发展论坛暨 2024长三角快递物流供应链与技术装备展览会(杭州) 时间&#xff1a;2024年4月12-14 日 地点&#xff1a;杭州国际博览中心 ESYE长三角快递物流展是亚洲范围内超大规模的快递物流业展示平台&#xff0c;由于展会的需求 及扩大市场的影响力…...

CSP 202203-1 未初始化警告

答题 要注意是xi和yi的范围&#xff0c;yi可以是0为常数。 #include<iostream> using namespace std;int main() {int n,k;cin>>n>>k;bool*initializenew bool[n]{false};int result0,x,y;while(k--){cin>>x>>y;if(y&&!initialize[y-1…...

开发指导—利用组件插值器动画实现 HarmonyOS 动效

一. 组件动画 在组件上创建和运行动画的快捷方式。具体用法请参考通用方法。 获取动画对象 通过调用 animate 方法获得 animation 对象&#xff0c;animation 对象支持动画属性、动画方法和动画事件。 <!-- xxx.hml --><div class"container"> <di…...

树莓派入门

目录 前言系统烧录使用官方烧录工具选择操作系统选择存储卡配置 Win32DiskImager 有屏幕树莓派开机树莓派关机无屏幕树莓派开机获取树莓派IP地址通过路由器获取共享网络方式获取给树莓派配置静态IP地址查找默认网关分盘给树莓派的IP地址修改树莓派DHCP配置文件 ssh登录 让树莓派…...

算法模型嵌入式 Mendix应用的开发示例

一、前言 根据埃森哲最新一项调查&#xff0c;2023年67%的企业持续加大在技术方面的投入&#xff0c;其中数据和AI应用是重中之重。AI在企业内部应用这个话题已经保持了十多年的热度&#xff0c;随着ChatGPT为代表的生成式AI技术的出现&#xff0c;这一话题迎来又一波的高潮。…...

如何使用Cygwin编译最新版的Redis源码,生成适用于Windows的Redis

文章目录 一、准备Cygwin环境二、下载Redis源码三、编译redis-7.2.01. 执行make命令2. 重新执行make命令3. 再次执行make命令4. 将编译后的可执行文件及依赖放到同一个文件夹5. 测试编译生成的可执行程序 四、换其他redis版本重新编译1. 编译redis-7.0.122. 编译redis-6.2.133.…...

Linux 修改SSH端口

如果防火墙&#xff0c;或防火墙已经开启&#xff0c;需要先开放2222端口 firewall-cmd --add-port2222/tcp --permanent --zonepublic firewall-cmd --reload编辑文件 vim /etc/ssh/sshd_config&#xff1a; #Port 22 Port 2222 # 打开注释&#xff0c;并修改为以下值 Clien…...

自己做网站能赚钱么/推广业务

创建git仓库 以github为例&#xff0c;登录账号建立一个仓库&#xff0c;然后将仓库地址copy下来。 本地目录 初始化$ git init 添加至版本库$ git add -A 提交$ git commit -m "first commit" 关联至远程仓库$ git remote add origin https://github.com/user/proje…...

知道域名怎么进入网站/广州关键词优化外包

间隔提取字符串字符 将字符数组str1种下标为偶数的元素赋值给另外一个字符数组str2。 /* 将字符数组str1种下标为偶数的元素赋值给另外一个字符数组str2。 */ #include<stdio.h> #define N 100 int main(){char str1[N],str2[N];scanf("%s",str1);char *pstr1…...

顺义重庆网站建设/竞价推广代运营公司

笔记本使用Android studio的adb wifi插件时&#xff0c;AS 最下方报 adb wifi scan ip address。一直无法使用。 解决办法&#xff1a; ----在Terminal窗口中输入&#xff1a; adb connect 192.X.X.X (你手机的ip) 手机ip可以通过wifi信息获取。 然后会显示&#xff1a; un…...

网页设计实验报告收获/优化方案怎么写

题目来源&#xff1a;K-A/virus_湖南大学2021届ACM新生赛&#xff08;重现赛&#xff09; (nowcoder.com) 翻译如下&#xff1a; 题目描述&#xff1a; Sakuyalove发现了一个三角形金字塔&#xff0c;其中包含许多具有自己的A /病毒值的节点。出于好奇&#xff0c;Sakuyalove…...

想在网站上放百度广告怎么做/网站设计流程

COCO数据集官网&#xff1a;http://cocodataset.org/#download $ wget -c 网址 其中&#xff0c;加上-c的意思是断点续传。 如果你们的网络很慢&#xff0c;可以考虑在晚上没人的时候下载。 train2017&#xff1a;http://images.cocodataset.org/zips/train2017.zip val2017…...

制作商务网站信息标题应/南宁百度推广代理商

Selenium Grid Parallel Test(C#)Author: Mars (hnynes)Email: hnynesgmail.comMSN: hnynesgmail.com前段时间由于项目中用到了Selenium Grid Test,只是(parallel)并行测试却一直没有做成功.昨天查了一个参数&#xff0c;感觉好像是并行了&#xff0c;但是testcase并未全部…...