(视频1- 4)
目录
1、类不带指针(例子:复数)【Object Based:面对的是单一class的设计】
2、类带指针(例子:字符串)【Object Oriented:面对的是多重classes的设计】
3.3.1 构造函数可以有很多个--overloading(重载)
3.9 相同class的各个object互为friends(友元)
1. C与C++
* 在C语言中,设计程序时,准备函数、数据,数据是一个类型,根据数据类型创建出许多的真正的数据,函数用于处理这些真正的数据;由于语言没有提供关键字,这些数据必定的全局的,在后续处理中,是有影响的。
* 在C++中,将数据与处理这些数据函数包在一起,数据只有处理他的函数才能看见,类似于C中的struct,但C++中的class与C中的struct相比,又多了许多其他的特性及关键字;C++的结构几乎等于class。以这个为一个类型去创建对象。(个人理解:在C++中,将数据和功能函数包在一起,作为一个class,struct;去创建对象,这些变量是局部的,其作用范围只存在于对应的class和struct中;此时的calss类似C语言中的一个小的程序)
* 对class的分类:里面带有指针(eg:复数)、里面不带指针(eg:字符串string)。
* #include<iostream> // 引用已存在的库
#include<cstdio> // 引用C的输入输出库【引入标准库】
#include"complex.h" // 引用自己写的库
1.1 C++对类的两种分类
1、类不带指针(例子:复数)【Object Based:面对的是单一class的设计】
数据有很多份,函数只有一份。
不带指针的类,多半不用析构函数。
2、类带指针(例子:字符串)【Object Oriented:面对的是多重classes的设计】
字符串的特色在于,他的里面只有一个指针,他的内容hello word是通 过这个指针指出去。s1、s2的大小就是一个指针。
3、这两种不同的类,其创建对象的方式也是有所不同的
【附】 C++ 学习
* C++可以分为:C++语言和C++标准库两个部分。相较于C语言而言,C语言主要是语言部分,其标准库部分有,但是运用很少。
* 《C++ Primer》C++的第一个编译器作者所编写的。(针对C++语言部分)
* 《C++ Programming Lanuage》C++之父所编写的。(针对C++语言部分)
* 《Effective C++中文版》(候捷)针对C++语言一些编写注意事项,怎么样会影响其效率,所作出的一些注意点(针对C++语言部分)
* 《STL源码剖析》(候捷)(针对于C++标准库部分)
2. 头文件
2.1 头文件中的防卫式声明
* 如果,不曾定义 _COMPLEX_ ,则定义_COMPLEX_ ;如果并未定义过,则执行方框中的程序,如果之前已经定义过,则不会进入到方框中,可避免头文件的重复引用,也可用于需要在引入xxx头文件之前需要先引入xxx头文件的情况。
2.2 头文件的布局
0:前置声明,1:类-声明,2:类-定义。
3. 类(complex--不带指针)
** friend:涉及另外一个类,另外一个单元,这两者之间是朋友的关系。
* public中,real()函数 和 imag()函数 直接在此处定义了(有{ });而对于complex() 函数而言,只是一个声明,没有{ },没有主体。
3.1 访问级别
* public:大家都可以看到;
private:只有该class自己可以看到;
protected:
左侧(创建一个对象,直接去拿)错误原因:其在private里面,不能够直接拿。
3.2 inline(内联)函数
* 函数在class body内定义完成,则自动成为inline候选人。但若函数太复杂, 则编译器没有办法变成inline函数。
* 用inline关键字,告诉编译器 尽量把我inline,但是最后是否能inline还是要看编译器。
3.3 构造函数
① 构造函数名,与class名相同;② 没有返回值类型--因为:构造函数是用于创造对象(class complex这种东西);③ “构造函数名 (double r = 0,double i = 0):(初值列,初始列)”是构造函数特有的语法,用于设初值、初始化--一个变量的数值设定有初始化和赋值这两个阶段, “(初值列,初始列)”是初始化,在 { } 中是去赋值;如果没有在 “(初值列,初始列)”中进行初始化 且 直接去赋值;两者出来结果一样,但是直接去赋值相比完整的两步而言,其时间节点要晚一些,效率也要差些。注意:此处是“:”之后可以有很多操作,最常见的是赋初始值。
下图:直接赋初始值。----这样可以,但是效率差一些。
与下图这种方法实现的最终的效果相同。但是上图的效率差。
直接初始化。
3.3.1 构造函数可以有很多个--overloading(重载)
函数重载常常发生在构造函数上。
下图中,1和2为一组,共两组例子。
* 设计一个类,外界创建对象,创建对象时怎么创建有很多种想法(eg:3种),则写出(eg:3种)几种想法;(有很多种初值的设定)。
** 正是因为函数可以重载,因此可以存在多个同名的函数,这些函数的区分,以其变量名及个数进行区分。
* 对于第一组(2后面有红色的?!的那一组),是错误的,不能这样写。
对于例子,complex c1; 和 complex c2(); 这两个都是创建一个新的参数c1,c2 且 没有给参数,仅仅是写法不同。
因为:在调用时,2的函数是(),没有参数;是候选人,
而1的函数虽然有参数,但是有默认值,也可以调用。
在这种情况下(构造函数有默认值),不允许2的存在,但是可以写其他的构造函数。
【注意】:构造函数1complex(double r = 0, double i = 0) : re(r),im(i){} 可以重载,但是不能重载为2的样子。
3.3.2 构造函数被放在private区
1、构造函数被放在private区,表示不允许被外界创造对象;
对于下图例子,非法调用构造函数(因为将构造函数在private区域后,不允许外界访问,非法)
2、构造函数放在private区。经典示例(设计模式中的单例模式):
Singleton:设计模式的一种。(单例,单体,单件)
在其内部,自己准备了一份自己 (static A a;),外界只能要一份,不允许外界创建。通过右侧的方式取。
3.4 析构函数
不带指针的类,多半可以不带析构函数。
【简 提】模板 简介
* 若要再设计一个类,此处的private中的参数为float、int等,其他类型;此时考虑用模板。
* 若在下侧中,采用第一行,则T为double型;若采用第二行,则T为int型。
3.5 const 常量成员函数
1、在函数后面加const,()的后面 {}的前面(适用于class里面的函数不会改变数据内容)。
* 对class里的函数,分改变数据内容和不改变数据内容的两类,对于不改变数据内容的 必须加const。
2、下方:左侧 √。右侧:第一行,我的对象是一个常量,若在class中未加const,而在用的时候加了const,此时编译器会告诉说 这种用不行,无法得到调用。
3.6 参数传递
* 第三处黄色高亮(const complex&)表示 pass by reference to const [通过引用传递给const对象]。(传to const过去,表示 我传进去之后,你不允许改这个内容)。
在2-7中的第一处高亮 ostream& 表示pass by reference [按引用传递]。(传指针过去,4个字节;引用就相当于传指针) (所有的参数尽量都传引用,传指针)。
* pass by value:整包传过去,压到函数的堆栈stack中。(尽量避免)
3.7 返回值传递
1、返回值的传递,尽量return by reference
3.8 friend(友元)
* 朋友打开了封装。
* 朋友是直接拿private成员。
3.9 相同class的各个object互为friends(友元)
【上述小结】:
1、设计一个类,① 数据一定在private,② 参数尽可能以reference来存,加const与否 看情况,③ 返回值也尽量以reference来存。
2、在class body中,应该加 const 的则加。
3、构造函数的 (初值列,初始列)这个特殊的语法,尽量去用他。
3.10 class body外的各种定义
* 一个函数是运算结果,一种是函数必须创建一个地方来让其进行放置(A),另一种是放到某个位置(现已存在)(B)。
* 在上方的函数中,为B种情况,
什么情况下可以pass by reference?什么情况下可以return by reference?
* 在A种情况下,不能return by reference。除此种情况外,均可 返回引用。