第四周 C++面向对象高级编程(下)Boolan

1. 导读

我们的目标

  • 在先前基础课程所培养的正规、大气的编程素养上,继续探讨更多技术。
  • 泛型编程(Generic Programming)和面向对象编程(Object-Oriented Programming)虽然分属不同思维,但它们正是 C++的技术主线,所以本课程也讨论template(模板)。
  • 深入探索面向对象的继承关系(inheritance)所形成的对象模型(Object Model),包括隐藏于底层的 this 指针,vptr(虚指针),vtbl(虚表),virtual mechanism(虚机制),以及虚函数(virtual functions)造成的 polymorphism(多态)效果。

2. 类型转换

转换有两种,一种是转出去,一种是转过来。

2.1 Conversion Function 转换函数

转换函数的作用是转出去,把这个类的值转换成其他的类型。


Conversion Function
operator double() const {……;}

定义了一个转换为 double 的函数,
没有参数,转换时不会带有参数。
不写返回类型,返回类型就是名称里这个double

  • 如果不改变值,就该加 const,否则后面可能会出错。
  • 只要认为合理,可以设计好几个转换函数。

模板的偏特化?
操作符重载

2.2 只有一个参数的构造函数

只有一个参数的构造函数可以将一个 int 或 float 值转换为该类对象。

2.2.1 non-explicit-on-argument ctor

non-explicit-on-argument ctor
Fraction (int num, int den=1): m_numerator(num), m_denominator(den) { }

分母默认是1,这样一个值构造为对象时,实际值不变。

Fraction operator+(const Fraction& f) { }

只能分数加分数

Fraction d2=f+4;

4可以转换为 Fraction,因为有一个构造函数只有一个int 参数。

2.2.2 conversion function vs. non-explicit-one argument ctor

conversion function vs. non-explicit-one argument ctor

当转换函数与非显式声明的一个参数的构造函数同时存在时,就会出现歧义。因为两种方式都可以编译。
多于一条路径可以编译,就会出现歧义,编译器就会报错。

[Error] ambiguous

2.2.3 explicit-one-argument ctor

explicit-one-argument ctor

显式声明就可以避免这个问题。

explicit Fraction(int num, int den=1):……

此时就会调用构造函数,而不会调用 double 转换函数。

conversion function

3. 模仿的类

3.1 pointer-like classes

设计一个类,模拟 pointer

3.1.1 关于智能指针

不同的语法

->用掉后,还有一个->,所以

sp->method();
px->method(); //转换完依旧有->

3.1.2 关于迭代器

迭代器中的指针操作

注意操作符重载
++ -- 适用于指针移动
Paste_Image.png

return (*node).data;  //取的是node 指向的块的数据
return &(operator()); //返回迭代器中内容的指针,而不是指向迭代器块的 node 的指针。

3.2 function-like classes,所谓仿函数

function-like classes
Paste_Image.png
Paste_Image.png
Paste_Image.png

unary_function 一个操作数
binary_function 两个操作数

4. namespace 经验谈

namespace
namespace jj01
{
}//namespace

5. 模板 template

5.1 class template

class template
template<typename T>

5.2. Function Template

Function Template
template <class T>

5.3 Member Template

Member Template
template <class T1, class T2>
struct pair {
……
  template <class U1, class U2>
  ……
}
Paste_Image.png
Paste_Image.png
Base1* ptr = new Derived1; //up-cast
shared_ptr<Base1>sptr(new Derived1); // 模拟 up-cast

5.4 specialization,模板特化

specialization
template<class Key>
struct hash {  } ;
template<>
struct hash<char> {   };

泛化对应特化,共性中的个性,用来应对特例。

5.4.1 partial specialization,模板偏特化

又称为局部特化

5.4.1.1 个数的偏

Paste_Image.png

< >尖括号内叫做模板参数

class vector<bool, Alloc> { };   // Alloc没改变,而 bool 设定了。

一定要从左到右,不能跳,不能135固定,24改变。

5.4.1.2 范围的偏

范围的偏

指针指向的偏

class c<T*> {   };  // 限定为指针

如果 T 是指针,使用偏特化模板。

5.5 template template parameter,模板模板参数

5.5.1 容器需要参数

容器需要参数
using Lst = list<T, allocator<>>;

模板需要好几个参数,必须替换

5.5.2 智能指针

智能指针

对应 SmartPtr,可以是……,不可以是……

5.5.3 这不是模板模板参数

这不是模板模板参数

已经绑定了,必须是这个,所以就没有模糊地带了。

6. 关于 C++ 标准库

Paste_Image.png

所有的容易算法都要用一遍。
编译器需要设定到 C++ 11

6.1 variadic templates (since C++11)

variadic templates

6.2 auto (since C++11)

auto

用 auto 时一定要让编译器能推出来。

auto ite = find(……)

find 的类型就是 auto 给 ite 的类型。


Paste_Image.png

auto 不能乱用,太长了、写不出来可以用。
我们一定要知道每个变量的定义是什么。

ranged-bas for (since C++11)

ranged-bas for
for ( decl : coll ) //左边是一个变量,右边必须是一个collector,容器
for ( int i : { 2, 3, 5, 7 } ){ }
vector<double> vec;
……
for ( auto elem : vec ) { cout << elem << endl ;} //传值
for ( auto& elem : vec ) { elem *= 3; } //传引用,尽量传引用

15. reference(引用)

reference

声明时一定要有初值,设完之后就不能再变了。


reference

object 和其 reference 的大小相同,地址也相同(全都是假象)
???那么新建一个 reference 会让程序新占用多少内存呢?

常见用途

常见用途

函数传参

void func3(Cls& obj) { obj.xxx(); }
func3(obj);

reference 通常不用于声明变量,而用于参数类型和返回类型的描述。
相同声明结构,仅仅传递引用和变量,会导致模糊,签名相同,所以不能同时存在。
是否加const,
???有什么区别?
加 const 会改变签名,是可以定义的。

7. 复合&继承关系下的构造和析构

7.1 Composition(复合)关系下的构造和析构

Composition(复合)关系下的构造和析构

Container 在外 Component 在内

7.2 Inheritance(继承)关系下的构造和析构

Inheritance(继承)关系下的构造和析构

Derive在外,Base 在内
由内而外构建
由外而内析构
子类析构函数会自动调用父类析构函数

Inheritance + Composition 关系下的构造和析构

Inheritance + Composition 关系下的构造和析构

不同编译器可能不同
观察到的结论是先调用 Base,后调用 Component

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

推荐阅读更多精彩内容