学习了Markdown以后,真是停不下来,以后笔记怕是离不开Markdown了。
这里只是展示一下效果,从为知到简书的转换实在是太手疼,以后不这么搞了TT
另外,笔记并没有整理完,哪有这么快的2333
0. 你应具备的基础
- 曾经学过某种过程语言(C语言最佳)
- 变量(variables)
- 类型(types):
int
,float
,char
,struct
... - 作用域(scope)
- 循环(loops):
while
,for
- 流程控制:
if-else
,switch-case
1. C++编程简介
我们的目标- 培养正规的、大气的变成习惯
-
以良好的方式编写C++ class(基于对象)
- class without pointer members - Complex
- class without pointer members -String
-
学习Classes之间的关系(面向对象)
- 继承(inheritance)
- 符合(composition)
- 委托(delegation)
你将获得的代码
complex.h
complex-test.cpp
string.h
string-test.cpp
C++的历史
- B语言(1969)
- C语言(1972)
- C++语言(1983)
(new C → C with Class → C++) - Java语言
- C#语言
C++演化
C++ 98 (1.0 )
C++ 03 (TR1)
C++ 11 (2.0)
C++ 14
Bibliography
C++ Primer
The C++ Programming Language
Effective C++ Third Edition
The C++ Standard Library Second Edition
STL源码剖析
C vs C++,关于数据和函数
C++,关于数据和函数
complex(复数)
数据可能有很多份,而函数只有一份
string(字符串)
数据其实是一个指针ptr
Object Based (基于对象) vs. Object Oriented (面向对象)
- Object Based :面对的是单一的 class 的设计
- Object Oriented:面对的是多重classes的设计,classes和classes之间的关系
我们的第一个C++程序
Classes的两个经典分类:
- Class without pointer member(s)
complex - Class with pointer member(s)
string
2. 头文件与类的声明
C++ 程序代码基本形式
- .h 头文件 声明
- .cpp 主程序
#include
- .h 标准库
扩展名不一定是.h 或.cpp
也可能是.hpp,甚至没有扩展名
Output, C++ vs. C
Header 头文件中的防卫式声明
#ifndef __COMPLEX__ //如果不曾定义COMPLEX的话,就定义
#define __COMPLEX__
……
#endif
Header头文件的布局
class 的声明(declaration)
class template 模板简介
3. 构造函数
inline 内联函数
- 声明(没有花括号的)
- 定义(有花括号的)
inline
函数若在class body内定义完成,便自动成为inline候选人
函数太复杂,就可无法变成inline,这由编译器决定
优点
像个壶?一样
不在本体中定义的,可以加inline
来定义。
access level 访问级别
- public
- private
- protected
可以交错
错的是因为调用了private的变量
constructor ctor 构造函数
自动调用的,不用自己去调用
??被调用的是什么?
构造函数的名称必须与类的名称一致,可以带有参数,可以有默认值
没有返回类型,不需要有
构造函数独有的语法:初始列,初值列initialization list
: re (r) , im (i)
和本体里赋值是一样的,但尽可能要这样写差别在于:
数值的设定有两阶段:
- 初始化
- 赋值
赋值相当于放弃了初始化的步骤,降低效率
不可能去手动调用构造函数,只能去创建对象,自动的就会调用构造函数。
这就是不带指针的类
不用写机构函数??
构造函数可以有很多个-overloading(重载)
函数名可以重复,但是不能都加const
函数被编译器处理后,很可能名字会变得很长
因为有默认值,所以不能像②那么写,因为调用时有歧义
complex () : re (0) , im (0) { }
变量尽可能放在private区,而函数尽可能放在public区
构造函数被放在private区
这时候就无法调用构造函数。
可以这么做,建立一个不能被调用的构造函数
ctors放在private区
单体singleton
4. 参数传递与返回值
const member functions (常量成员函数)
在函数后面加const,不改变数据内容
设计的时候就应该知道需不需要加,不加的话就会出问题
编译时会出错。
参数传递:pass by value vs. pass by reference(to const)
传递值,与传递关系,传递引用
引用
底层就是一个指针,但是形式又很漂亮
最好所有的参数传递都传引用,尽量不要传值(有的时候不可以)
如果希望不能改这个值,就加const
返回值传递:return by value vs. return by reference(to const)
friend(友元)
朋友可以来拿的数据
friend complex& __doapl ()
__doapl
可以直接使用private中的re
和im
相同 class 的各个 objects 互为 friends (友元)
注意这几点
- 数据一定放在private
- 参数尽可能以引用来传
- 要不要加const,需要就加,不加可能在使用的时候会报错
- 构造函数,特殊的语法,初始列
class body 外的各种定义(definitions)
什么情况下不能 return by reference
- 函数必须新创建一个位置去放,函数运行完,这个变量就消失了,这时候必须传数据
- 函数把新值放在其中一个位置,这时可以传reference
5. 操作符重载与临时对象
operator overloading (操作符重载-1,成员函数) this
在C++里操作数就是一种函数,可以重新定义
编译器如何看待操作符
二元操作数
左操作数,右操作数
隐藏参数(this)
调用者就是this
c2是一个指针,地址被传入this
__doapl do assignment plus
任何一个成员函数都有一个隐藏的函数:this pointer
return by reference 语法分析
左操作数是个指针
返回的是一个数据
说明的是返回的是一个引用
传递者无需知道接受者是以reference形式接收
接收pointer必须传pointer
接收reference可以传value
要先想到会怎么用,比如说连串的赋值(使用),所以要注意返回值
class body 之外的各种定义(definitions)
虚部和实部
operator overloading (操作符重载-2,非成员函数)(无this)
为了应对client的三种可能用法,这里对应开发了三个函数
复数+复数
复数+实数
实数+复数
全域、全局函数,没有this pointer
temp object (临时对象) typename ();
返回的为什么不是reference
因为它们返回的必定是一个local object
特殊语法:
typename();
类似于int(i+j);
创建临时对象,没有名称
一个习题,把+改成reference,看看能不能运作
inline complex&
operator overloading (操作符重载),非成员函数
参数的传递快不快?
返回的时候快不快?
operator overloading (操作符重载),非成员函数
operator overloading (操作符重载),非成员函数
<<操作符的重载
解释成
cout
可以理解的形式
cout
是个对象,是什么type,要去查手册
能不能在接受类型处加const?不行,因为可能变成连串