目录
面向过程与面向对象区分
面向过程(Procedure Oriented 简称PO):
当解决一个问题的时候,面向过程会把事情拆分成: 一个个函数和数据。然后按照一定的顺序,执行完这些方法,事情就搞定了。
面向对象(Object Oriented 简称OO):
当解决一个问题的时候,面向对象会把事物抽象成对象的概念,就是说这个问题里 面有哪些对象,然后给对象赋一些属性和方法,然后让每个对象去执行自己的方 法,问题得到解决。
class
类
类:对某一事物的抽象
在 c++ 语言中是一种数据类型,用于描述某一个类的事物,包括属性与方法(函数)
定义:
对象
定义:具体化某一个事物,成为一个具体的个体,创建对象后才会分配内存空间
创建方式
1、<类名> <对象名>; //创建对象并分配内存
2、<类名> *<对象指针名> = new <类名>(); //动态创建对象 ,需要主动释放对象,否则会造成内存泄漏
释放对象
语义: delete <对象名>;
注:数组的释放则需在对象名前加[], 列如:delete []data;
访问属性与方法
1、<对象名>.<属性或方法>; // 用于普通对象
2、<对象指针名>-><属性或方法>; // 用于对象指针
访问权限
class默认权限是private。
public (公有的) : 一个类的public成员变量、成员函数,可以通过类的成员函数、类的实例变量进行访问
private (私有的):一个类的private成员变量、成员函数,无法通过类的实例变量进行访问。但是可以通过类的友元函数、友元类进行访问。
protected (受保护的):一个类的protected成员变量、成员函数,无法通过类的实例变量进行访问。但是可以通过类的友元函数、友元类进行访问。
注:在访问权限中体现不出来他们的差别,在继承中才会体现出不同
构造函数
在构造对象时自动调用此函数,往往用来初始化对象内的成员变量。
定义:函数名与类名一致且没有返回值
列:
默认构造函数
定义:当类中没有构造函数时,编译器会自动生成一个构造函数。
构造函数的重载
定义:针对不同的初始化方式,可以重载构造函数。
列:
初始化列表
在初始化时,也可以使用初始化列表的方式来实现构造函数, 一般用在继承中。
列:
拷贝构造函数
当一个对象需要通过另一个对象初始化,则需要使用拷贝构造函数。
什么时间会调用拷贝构造函数?
1、主动创建对象时,用一个对象去初始化另一个对象的时候
2、一个对象以值传递的形式传入函数体,如果是引用传递则不会调用
int get_a(A aa) //参数是对象,是值传递,会调用拷贝构造函数
{
return aa.geta();
}
int get_a1(A &aa) //如果参数是引用类型,本身就是引用传递,所以不会调用拷贝构造函数
{
return aa.geta();
}
int main()
{
int i=get_a(a1); //函数形参是类的对象,调用拷贝构造函数
int j=get_a1(a1); //函数形参类型是引用,不调用拷贝构造函数
}
3、一个对象以值的形式从函数返回
//C++标准允许一种(编译器)实现省略创建一个只是为了初始化另一个同类型对象的临时对象。指定这个参数(-fno-elide-constructors)将关闭这种优化 。
优化方式是建立一个对象引用绑定到返回的优化, 可以省略两次调用拷贝构造函数 。
深拷贝与浅拷贝
浅拷贝: 1、默认的拷贝构造函数为浅拷贝
2、针对指针对象,只拷贝指针存储的地址。//由于指向同一个空间,改变一个,另一个也会改变。
深拷贝:针对指针对象,拷贝指针指向的空间。 //两者互不影响。
explicit
含义:explicit关键字只能用来修饰类的构造函数,且最好只修饰只有一个参数的构造函数被修饰的构造函数不能发生相应的隐式类型转换,只能以显示的方式进行类型转换
何时触发隐式拷贝构造函数?
1、一个对象作为函数参数,以值传递的方式传入函数体
2、一个对象作为函数返回值,以值传递的方式从函数返回
3、以A a = b的方式构造a,其中b也是A类型
所以在拷贝构造函数一般不会设计成禁止隐式转换
析构函数
在销毁对象时自动调用此函数,往往用来释放对象内申请的资源
定义: 与类名相同,在前面加位取反符~,且不能有任何参数与返回值。
示例:
特点:
没有参数没有返回值,但有this指针
析构函数不能用const修饰
一个类有且只有一个析构函数,所以肯定不能重载
static
static表示静态关键字,可以用于修饰成员变量与成员函数。
静态成员可以通过双冒号来使用,即 <类名>::<静态成员名>
修饰成员变量
语法:1、在 class 中进行声明 static <类型修饰符> <变量名>
2、在 class 外进行初始化 <类型修饰符><类名>::<变量名> = <初始化值>
特点:
static 修饰的成员变量属于类不属于具体的对象。
static 成员变量的内存在程序开始运行时分配,程序运行结束时释放内存。
static 成员变量对于所有的对象是共享的,并在对象创建之前就已经产生了。
静态成员使用前必须初始化,否则会在linker(链接)步骤时出错。
在成员函数中可以正常访问静态成员变量。
修饰成员函数
语法: static <函数返回值><函数名>(参数列表)
特点:
可以被对象直接使用
可以通过类名直接访问
不能使用 this 指针,与类关联,不与对象关联,在调用静态函数时,可以在没有对象时调用
不能访问非静态成员,只能访问静态成员
何时使用static?
一切不需要实例化(创建对象)就可以有确定行为方式的函数都应该设计成静态的。
this指针
用于保存对象的地址,每一个非静态函数中都有一个隐藏参数this
常见使用方式:
在非静态函数中,需要返回对象本身
在非静态函数中,传入形参名与对象内成员变量
相同时区分两个变量
const
const成员变量
const成员变量只能在初始化列表中初始化
const成员函数
防止成员函数修改非静态成员变量的值
const成员函数可以修改静态成员变量
const成员函数也可以与同名非const成员函数构成函数重载
创建const对象时调用的为const修饰的成员函数
友元
友元函数
概念 :1、友元函数不是成员函数,它定义在类的外部,只需要在类中声明即可
2、友元函数可以访问所有私有成员和保护成员,一般情况下不去使用,使用不当会破坏程序面向对象的特性
语法: friend <函数声明>
友元类
概念:1、一个类声明另一个类是自己的友元
2、假如类A声明类B是自己的友元,那么在类B中可以 访问类A所有的私有成员和保护成员
语法:friend <类名>
注意:
1、 友元不具有相互性,若类B是类A的友元,类A不一定是类B的友元
2、友元不能被继承
3、你爹的朋友不一定是你的朋友
4、友元不具有传递性
5、你朋友的朋友不一定是你的朋友
内联函数
目的:引入内联函数的目的是为了解决程序中函数调用的效率问题
原理:内联函数在编译器阶段是直接复制“镶嵌”到主函数中去的,就是将内联函数的代码直接放在内联函数的位置 上,这与一般函数不同,主函数在调用一般函数的时候,是指令跳转到被调用函数的入口地址,执行完被调 用函数后,指令再跳转回主函数上继续执行后面的代码;而由于内联函数是将函数的代码直接放在了函数的 位置上,所以没有指令跳转,指令按顺序执行
语法:1、函数声明和定义必须在同一文件进行,声明与定 义时需要添加inline修饰符
inline <返回值> <函数名>(<形参表>) {<函数体>}
2、内联函数内不允许使用循环语句与开关语句
3、内联函数不能超过10行,如果超过则编译器不会 替换,而还是使用调用的方式调用函数
类与内联函数:
类内定义的函数都是内敛函数,不管是否有inline修饰符
声明在类内,定义在类外,看是否有inline修饰符
与宏定义的区别:
宏是由预处理器进行代码替换,而内联函数由编译器进行代码替换
内联函数是真正的函数