美文网首页
第四周 C++面向对象高级编程(下)Boolan

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

作者: 一般的路人丙 | 来源:发表于2017-02-23 18:47 被阅读0次

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

相关文章

网友评论

      本文标题:第四周 C++面向对象高级编程(下)Boolan

      本文链接:https://www.haomeiwen.com/subject/grazbttx.html