一起读《Effective C++》: 条款01:视C++为一个语言联邦

文章目录

  • 一起读《Effective C++》: 条款01:视C++为一个语言联邦
  • 条款01:视C++为一个语言联邦
    • 一起读
  • 知识点补充
    • 知识点一:泛型编程
    • 知识点二:模板函数、模板函数的实例化与具体化
    • 知识点三:类模板(顺带一提模板类)
    • 知识点四:成员模板

我写这篇文章的主旨就是尽量用我理解的人话和充足的知识点补充来帮助实验室的兄弟姐妹吃透《Effective C++》这本书,因为这本书已经算作是C++较为高级和深入的用法,涉及到的很多知识点书中并没有给出,基本上就是甩出了一个概念(),
《Effective C++》作为一本提升C++能力的必读书籍,每次阅读都挺吃力的,因为菜(bushi),很多时候面对的是“递归式学习”:书中的一个知识点看不懂,然后去查阅资料,查阅资料的时候又发现还有别的知识点看不懂,然后一直递归,o(╥﹏╥)o。
我在这里想把阅读这本佳作的学习过程记录下来,以方便自己和 实验室的其他同学学习C++。

条款01:视C++为一个语言联邦

View C++ as a federation of languages.

一起读

这个条款告诉你,C++并不是单纯地一个独立的孤儿(亚索)语言,而应该看作是由四个不同的部分所共同组建而成的,他们分别是:

  1. C。C++毕竟是C的自增嘛,C语言中涉及到的基本语法和关键字还是要遵守的,还有万恶之源(bushi)指针也来自C。
  2. 面向对象的C++。Object-Oriented C++,这部分在工作和学习中遇到的最多,基本上以后遇到的C++代码全部都是基于面向对象的。
  3. 泛型编程(说穿了就是模板)。这里我要讲个题外话,泛型generic programming中的generic的翻译是“通用的,一般的”,之所以翻译成为了“泛型”,是因为一开始搞编程的大佬不是有数学背景就是有物理学背景,这个概念在数学里的使用更为常见。UE4 的优秀代码中很多都是generic programming的,晦涩难懂(╥╯^╰╥),遇到的顶级源码基本都采用这种形式。相关的知识点我放在了下面的 知识点一:泛型编程 里面。
  4. STL。STL有自己的特殊的办事方式和脾气,要遵守STL特有的规则。

知识点补充

知识点一:泛型编程

推荐阅读文章
模板函数:
https://www.cnblogs.com/horacle/p/13701314.html#_caption_0
https://blog.csdn.net/gouzi668/article/details/107257849
类模板:
https://www.jianshu.com/p/70ca94872418
https://blog.csdn.net/qq_28351609/article/details/84631960
函数模板:
https://blog.csdn.net/weixin_38739598/article/details/111599558

我们遇到的泛型编程基本分为三大类:模板函数, 类模板,成员模板。我会在下面补充这些知识点。


知识点二:模板函数、模板函数的实例化与具体化

模板函数大家应该都用过,基本用法(其实是隐式实例化)就是先template定义类然后使用时给类型就行(如下)。其他常见的用法有两种分别是 函数模板显式实例化和具体化。

//模板函数一般用法(隐式实例化)
template <typename T>
void swap(T &a, T &b)
{ T temp;temp = a;a = b;b = temp;
}
  • 隐式实例化意思就是我只告诉了一个暂定的类代号叫T,这个T具体是什么类型我暂时不告诉你,等到用的时候再告诉你,有点像是隐形刺客,平时是隐身但是存在的,只有他下手的时候你才能看见他。
  • 显式实例化则像是一个一个正大光明拿着两板斧子的战士(奎爷那种),创建的时候就会实例化,无论该函数有没有被调用执行,编译器都会生成一个实例函数。 显式实例化只需要声明,因为他的作用就是告诉编译器我以后可能会大量频繁地调用这个类型的模板函数,所以你最好事先准备好,就不用每次都找隐式实例化然后再根据类型再实例化。
//模板函数的显式实例化
//在隐式实例化后面,仅仅需要声明就行
template void swap<int>(int& a, int& b);
  • 具体化有点类似重载,同名函数调用时会屏蔽通用模板函数并被优先选择。
    因为虽然都是swap,某个特殊的类可能会有特异的实现方法,所以需要单独重写一个swap防止它调用通用的模板函数,这就是具体化模板函数的应用场景。
//模板函数的具体化
template<>
void swap<special>(special &j1, special &j2);

知识点三:类模板(顺带一提模板类)

类模板

题外话:“类模板”与“模板类”
模板类是类模板实例化后的一个产物,说个具体点的例子吧,我们把类模板比作是一个做饼干的模子,而模板类就是用这个模子做出来的饼干,至于这个饼干是什么味道的就要看你自己在实例化时用的是什么材料了,你可以做巧克力饼干,也可以做牛奶饼干,这些饼干出了材料不一样外,其它的东西都是一样的了。

类模板就是 类里面涉及到部分的变量是不能确定的类型,所以要用模板来作为代号。

这个部分UE4源码里面用的多(Unity不太熟所以不清楚),经常会遇到各种继承的模板类(就很恶心),在继承的时候需要注意的基本有两点:

  • 如果父类自定义了构造函数,记得子类要使用构造函数列表来初始化。这点在UE4的源码里面非常常见,经常可以看到Child(参数一,参数二):Parent(参数一)这带构造函数列表的构造函数,而且源码中的父类都会有模板函数,所以你自己写的时候基本都需要再写一个子类的构造函数。
  • 如果子类不是模板类,那就必须要在定义的时候实例化父类的T类型;
    如果子类是模板类,那要么直接实例化T的类型,要么用子类的泛型实例化T的类型。
//父类模板类
template <typename T>
class Parent{public:Parent(T p){this->p = p;}private:T p;
};//如果子类不是模板类,需要指明父类的具体类型,直接实例化
class ChildOne:public Parent<int>{public:ChildOne(int a,int b):Parent(b)      //  构造函数列表来初始化父类{this->cone = a;}private:int cone;
};//如果子类是模板类,可以用子类的泛型来表示父类,也可以像上一个类一样直接实例化父类
template <typename T>
class ChildTwo:public Parent<T>{public:ChildTwo(T a, T b):Parent<T>(b){this->ctwo = a;}private:T ctwo;
};

类模板中涉及友元的部分我们以后再聊


知识点四:成员模板

成员模板分两种,一种是在普通类里面的成员模板 ,另一种是在类模板中的成员模板。

普通类里的成员模板:

#include <iostream>
using namespace std;class A{public:template<typename T>void function(const T &a){cout<<typeid(a).name();cout<<":"<<a<<endl;}
};int main(void) {A a1;a1.function(20);a1.function("Hellow World!");a1.function(0);return 0;
}//输出结果如下图右侧

普通类里的成员模板有自动推导(deduce)的功能,即使不指明和实例化类型也可以。需要注意的是这里Line7处的const,没有const的话过不了编译,提示:

error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'a1.function(20);^

类模板里的成员模板则不太一样:

  • 类模板的模板参数必须用<>指定,成员函数模板的参数可以由编译器自动推断(deduce),需要deduce自动推导的变量必须是const类型
  • 类模板的成员函数(包括普通成员函数/成员函数模板)只有为程序所用才进行实例化。
  • 如果某函数从未被使用,则不会实例化该成员函数。

示例如下:

#include <iostream>
using namespace std;template <typename T_A>
class A{public:template<typename T_A1>A(T_A _a,const T_A1 &_a1);  //需要deduce自动推导的变量必须是const类型void get_a(){cout<<typeid(t_a).name();cout<<":_a="<<t_a<<endl;}private:T_A t_a;
};template<typename T_A>  //先跟类的模板参数列表
template<typename T_A1>   //再跟构造函数自己的模板参数列表
A<T_A>::A(T_A _a,const T_A1 &_a1){cout<<_a1<<endl;t_a=_a;
}int main(void) {//类模板的模板参数必须用<>指定,成员函数模板(函数模板)的参数可以由编译器自动推断A<float> a1(16.99,15.01);a1.get_a();A<int> a2(16.99,15.01);a2.get_a();return 0;
}//输出结果如下图右侧

一起读《Effective C++》: 条款01:视C++为一个语言联邦相关推荐

  1. Effective C++条款01: 视C++为一个语言联邦

    一开始C++定义为:C with Classes. 如今的C++已经是一个多重范型编程语言,可以把C++视为有四个次语言组成的联邦语言. C.C++任然以C为基础.区块.语句.预处理.内置语言类型.数 ...

  2. 【effective c++笔记】条款01 :视c++为一个语言联邦

    c++的4个组成部分: (1)c:c++以c为基础. (2)面向对象设计的c++:包括classes(构造函数和析构函数),封装,继承,多态,virtual函数.... (3)Template C++ ...

  3. EffectiveC++-条款01:视C++为一个语言联邦

    一. 内容 C++ 最初的名字为 C with Classes. 今天的 C++ 已经是个 多重 范型 编程语言 同时支持 过程形式(procedural) 面向对象(object-oriented) ...

  4. 条款01:视C++为一个语言联邦

    C++由四部分组成: 1)C. 2)Object-Oriented C++.classes,封装,多态,动态绑定(virtual函数) 3)Template C++.泛型编程. 4)STL. 对于内置 ...

  5. 【01】视C++为一个语言联邦

    1.C++是个多重范型编程语言:面向过程,面向对象,函数编程,泛型形式,元编程形式. 2.C++是一个语言联邦,包括四个次语言: a.C语言,C++以C语言为基础.但C语言有下列局限:没有模版,没有异 ...

  6. Effective C++ 条款1、2、3、4

    以下内容均来自Scott Meyers大师所著Effective C++ version3,如有错误地方,欢迎指正!相互学习,促进!! 条款1 视C++为一个语言联邦 理解C++,须认识其主要的次语言 ...

  7. 【Effection C++】读书笔记 条款01~条款04

    [Effection C++]读书笔记 Part1 让自己习惯C++ 条款01:视C++为一个语言联邦 将C++视为一个由相关语言组成的联邦.在其某个次语言中,各种守则简单易懂,容易记住.但当从一个次 ...

  8. Effective C++条款(第三版-侯杰译)

    条款一:视C++为一个语言联邦 [C++高效编程守则视情况而变化,取决于你使用的C++哪一部分] 条款二:尽量以const,enum,inline替换#define [对于单纯变量,最好以const对 ...

  9. Effective C++ --条款1

    视c++为一个语言联邦 c++分为多个次语言. 1.以C为基础.面向过程 相同点:语句 预处理器 内置数据类型 数组 指针-- C的独特性及不足:没有模板 没有异常 没有重-- 2.面向对象的C++ ...

最新文章

  1. 设计模式之桥接模式(Bridge)摘录
  2. Fastlane- app自动编译、打包多个版本、上传到app store
  3. php ci laravel,PHP 框架 ci 和 laravel 的问题
  4. 图像拼接和图像融合技术
  5. java序列化 jar_使用序列化将对象传递给另一个JVM – 相同的Java版本和jar(都运行我们的应用程序)...
  6. asp.net通用用户初始化类,登录后初始化,随时随地可以应用
  7. python各版本区别_关于python中不同版本的print区别
  8. excel不显示0_【周一实用技巧】绝密,保护公式不被修改。Excel单元格保护可以输入但不能修改公式,隐藏不显示公式内容...
  9. sop4封装尺寸图_妈妈再也不用担心我PCB封装又做错了~
  10. relu函数_【AI初识境】激活函数:从人工设计(sigmoid,relu)到自动搜索(swish)
  11. 仓位管理 – 2.实战篇
  12. 论文阅读笔记(一)——DESCENDING THROUGH A CROWDED VALLEY—BENCHMARKING DEEP LEARNING OPTIMIZERS
  13. OSPF 的六种 LSA类型
  14. python编程练习-完美数
  15. 计算机无法识别打印机usb,win10电脑不识别打印机usb设备怎么回事_win10无法识别usb打印机如何处理-win7之家...
  16. js实现签名功能(vue中使用电子签名)
  17. 微信小程序显示html内容
  18. 千古以來:卍佛一心)悟道真机(转载)
  19. linux环境下(SUSE 11)安装ArcSDE 10.0 的注意事项(Oracle 11g)
  20. python-windows安装cuda+cudnn+pytorch

热门文章

  1. mongodb gridfs java_mongodb Gridfs操作
  2. 三大通信协议(二):IIC通信协议
  3. 高效程序员必备的六大命令行工具
  4. 周鸿祎对企业的深刻反思
  5. [年度计划]2017年年度学习规划
  6. 支付宝直连商户开通步骤
  7. java 数据立方_写一个Java应用程序,从键盘输入一个整数,然后输出它的平方值立方值...
  8. “收费”了微信,红了Line
  9. linux复制粘贴命令
  10. win10禁用驱动签名