侯捷C++教程笔记

[toc]

C++面向对象高级开发(全集)

https://www.bilibili.com/video/BV1K4411974P?p=1

C++编程简介

C++ 演化

书籍推荐:
effective C++

stl源码剖析

C vs C++ 关于数据和函数

c通过type(built-in,struct)创建出变量
C++通过class,struct(包含成员和函数)创建出对象

类的经典分类:带指针(复数)和不带指针(string)

object based vs. object oriented

Object based:面对单一class的设计
Object Oriented:面对多重classes的设计,类之间的关系。

C++程序的代码基本形式

.h (“ ”)+ .cpp + .h(标准库,<>)

c和c++的输出

cout和printf

头文件中的guard声明

第一次引用才定义,定义过则不过重复引用

#ifndef __header_name__
#define __header_name__

#endif

头文件的布局

#ifndef  __header_name__
#define  __header_name__

1.前置声明
class ostream;
class complex;

2.类-声明
class complex
{

}

3.类-定义
complex::function..
#endif

class的声明(declaration)

class complex //class head 
{
//class body
}

模板(template)简介

template<typename T>


image.png

构造函数

inlinx(内联)函数

函数在class body内定义完成
运行较快。函数体简单
(最终由编译器决定是否为内联)
(现在编译器自动进行内联优化)

access level 访问级别

public
private
protect

构造函数 constructor

名称同类名,不需要返回值类型。


image.png

构造函数的特别语法↑
initialization list (大气!!!)
简单的差别:赋值过程不一样,能提高效率

不带指针的类多半不用写析构函数

构造函数可以有很多个--overloading(重载)

编译器编译后形成两个名称的函数

参数传递与返回值

singleton 单例 类
构造函数放在private里

const member functions 常量成员函数

在函数后加const -->拿数据而不改变数据内容


image.png

大家风范!

参数传递:pass by value(形参) vs. pass by reference(to const)

引用& 在底层相当于传递指针一样快。
(侯捷老师:良好习惯:最好传引用)
如果不想修改原引用值
使用const name&

参数一字节/两字节:可以形参

返回值传递:return by value vs. return by reference(to const)

返回值 如果可以--> 使用 引用传递

friend(友元)

友元函数可以自由取得friend 的 private成员

相同class的各个objects 互为friends(友元)

class body外的各种定义(definitions)

什么情况下可以pass by reference

什么情况下可以return by reference

  • 一个函数运算结果的存放位置,如果是新开辟的local 变量,则不可以使用引用。
  • 运算结果存在位置在函数结束后不会释放,则可以使用引用传递

操作符重载与临时对象

操作符重载-1 operator overload 成员函数 this

重载函数可以是成员函数或非成员函数
<< 只能写成非成员函数
传递者无需知道接收者是以reference形式接收


image.png
image.png

临时对象 typename();

image.png

--> return by value

类名typename(),-->创建一个临时对象-->类似于int() 强制类型转换?

注意点

  • 考虑该不该加const
  • 传递 是否用引用
  • 返回是否用引用
  • 数据放在private
  • 函数 位置

复习complex类的实现过程

考虑函数是否加const

三大函数:拷贝构造、拷贝复制、析构函数

Class with pointer member

举例:string class

指针类构造函数设计

带指针要自己写赋值拷贝

image.png

框中一套函数
第二行 拷贝构造
第三行 拷贝赋值(带指针得类一定要写)
第四行 析构函数(释放动态内存分配到的内存)
//一出手就要不同凡响


image.png

拷贝构造

默认的赋值会将两个指针指向同一地址
而不是开辟一块新的内存地址存放字符串。
浅拷贝:指针拷贝,将第二个指针指向同一地址->可能会造成内存泄漏
深拷贝:开辟一块新的内存空间,存放数据,并将新的指针指向新的地址。


深拷贝

拷贝赋值函数

image.png

↑经典写法->大家风范
先释放掉自己,然后new,然后拷贝。
一定要在op= 中检查是否为自我赋值

堆 heap 栈stack 与内存管理

介绍了heap、stack的概念 作用域
static 在作用域结束之后仍然存在,直到程序结束
heap object 结束时需要delete 掉

new:先分配memory 再调用构造函数
delete:先调用析构函数,再释放memory

动态分配所得的memory block in VC

动态分配的array

array new [] 搭配 array delete []

复习string类的实现过程

模板类、函数模板及其他

static

static静态数据只有一份(记得 在类外 定义/初始化)
type classname::name = 8.0;
静态函数 只能 存取 处理 静态数据

调用static函数的方式:
1.通过对象调用
2.通过class name 调用

image.png

单例类 只有唯一一个
单例模式/singleton

cout

类模板 class template

template<typename T>

function template 函数模板

template<class T>


image.png

编译器会自动推导出参数是哪类

特化/偏特化 等等

namespace

using directive;//不用写全名
using declaration;//打开某一行或几行

更多细节与深入

image.png

组合与继承

类间的关系

  • Inheritance(继承
  • Composition(复合
  • Delegation(委托

composition(复合),表示has-a

image.png

类内包含另一个类

//适配器模式

image.png

内存观察

composition关系下的构造和析构

构造函数由内而外
析构函数由外而内

Delegation(委托)。compostion by reference

image.png

rep是指针指向(与复合相比,寿命不一致,不是同步创建)

Inheritance(继承),表示is-a

父类数据可以完全继承

虚函数搭配最有价值

继承下的构造和析构

  • 构造由内而外:先父类,再子类
  • 析构由外而内:先子类再父类

虚函数与多态

继承和虚函数

  • non-virtual函数:不希望子类重新定义的函数
  • virtual函数:希望子类重新定义,并且已有默认定义(可以是空虚函数)
  • pure virtual函数:希望子类一定要重新定义,且没有默认定义

委托相关设计

23个经典设计模式

  • 类设计的三把大刀。(复合 委托 继承)

导读

conversion function 转换函数

image.png

重载了double转换类型

non-explicit-one-argument ctor

explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式).
explicit关键字只对有一个参数的类构造函数有效, 如果类构造函数参数大于或等于两个时, 是不会产生隐式转换的, 所以explicit关键字也就无效了


image.png
image.png

这种情况会出现语法冲突。

explicit-one-argument ctor

image.png
  • explict 只用在构造函数前

pointer-like classes,关于智能指针

智能指针->share_ptr->像指针的类

image.png

智能指针在语法上有三个很关键的地方,第一个是保存的外部指针,对应于上图的T* px,这个指针将代替传入指针进行相关传入指针的操作;第二个是重载“*”运算符,解引用,返回一个指针所指向的对象;第三个是重载“->”运算符,返回一个指针,对应于上图就是px。

关于迭代器

迭代器也是一种智能指针,这里也存在上面提到的智能指针的三个要素
注意操作符重载

image.png

创建一个list迭代器对象,list::iterator ite;这里的list用于保存Foo对象,也就是list模板定义里的class T,operator()返回的是一个(node).data对象,node是__link_type类型,然而__link_type又是__list_node<T>类型,这里的T是Foo,所以node是__list_node<Foo>类型,所以(node).data得到的是Foo类型的一个对象,而&(operator())最终得到的是该Foo对象的一个地址,即返回Foo* 类型的一个指针。

function-like classes 仿函数

让类像 一个函数??
“()”函数调用操作符(这我还真的第一次知道这么叫)
重载符号"()",就成为了一种仿函数
都会继承一些奇怪的父类->在c++标准库课程中讲解

namespace 经验谈

image.png

隔离一些可能命名重复的函数,避免冲突

class template,类模板

同之前

function template 函数模板

member template 成员模板

image.png

黄色代码段本身是一个模板中的成员,它自身又是一个模板。
成员模板在泛型编程里用得较多,为了有更好的可扩展性,以上图为例,T1往往是U1的基类,T2往往是U2的基类


image.png

通过这种方法,只要传入的U1和U2的父类或者祖类是T1和T2,那么通过这样的方式可以实现继承和多态的巧妙利用,但反之就不行了。这样的方式在STL中用得很多

specialization 模板特化

泛化->模板
特化->模板中指定特定的数据类型


image.png

partial specialization 模板偏特化

1.个数上的偏


image.png

2.范围上的偏


image.png

使用指针指向任意类型

template template parameter 模板的模板参数

image.png

容器需要好几个模板参数


[图片上传中...(image.png-53fe7b-1606466890066-0)]

image.png
image.png

↑ list<int> 绑定好了类型,不算模板参数

关于c++标准库

image.png
  • 容器
  • 算法
    c++11在另一门课

三个主题

variadic templates(c++11) 数量不定的模板参数

image.png

允许写任意个数的模板参数 “..."已经作为语法的一部分
多个模板参数进行递归调用。

auto

image.png

ranged-base for

for循环的新语法

image.png

reference

image.png

reference一定要有初值。
初值设置之后不可以改变代表对象。

r = x2 一行相当于给r赋值 使r为5 导致x也为5

image.png

image.png

const 是函数签名的一部分

复合&继承关系下的构造与析构

同之前

关于vptr和vtbl (虚指针、虚函数表

image.png

vptr指向vtbl 然后找到虚函数地址,找到对应函数

定义了三个类,A、B和C,B继承于A,C继承于B,A中有两个虚函数,B中有一个,C中也有一个。编译器将A的对象a在内存中分配如上图所示,只有两个成员变量m_data1和m_data2,与此同时,由于A类有虚函数,编译器将给a对象分配一个空间用于保存虚函数表,这张表维护着该类的虚函数地址(动态绑定),由于A类有两个虚函数,于是a的虚函数表中有两个空间(黄蓝空间)分别指向A::vfunc1()和A::vfunc2();同样的,b是B类的一个对象,由于B类重写了A类的vfunc1()函数,所以B的虚函数表(青色部分)将指向B::vfunc1(),同时B继承了A类的vfunc2(),所以B的虚函数表(蓝色部分)将指向父类A的A::vfunc2()函数;同样的,c是C类的一个对象,由于C类重写了父类的vfunc1()函数,所以C的虚函数表(黄色部分)将指向C::vfunc1(),同时C继承了超类A的vfunc2(),所以B的虚函数表(蓝色部分)将指向A::vfunc2()函数。同时上图也用C语言代码说明了编译器底层是如何调用这些函数的,这便是面向对象继承多态的本质。

this指针

image.png

通过一个对象来调用,对象的地址就是this

关于动态绑定 dynamic binding

image.png
image.png
image.png

STL源码分析|c++标准库体系结构与内核分析

认识headers、版本、重要资源

使用一个东西,却不明白它的道理,不高明!
目标:使用c++标准库-》认识c++标准库 ->良好使用c++标准库->扩充c++标准库

重要网页

www.cplusplus.com
www.cppreference.com
www.gcc.gnu.org

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容