C++学习笔记

2021/9/10 22:35:50

本文主要是介绍C++学习笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

C++中的多态:
1、c++中的抽象基类不能实例化,但是可以有构造函数和析构函数,抽象基类里面的方法可以不全是虚方法。
(java语言中抽象基类也可以有构造函数,但也不能实例化,所含方法也可以不全是抽象方法)。

2、根据一般规则,凡基类中定义有一个或多个虚函数,因该要将析构函数声明为虚函数
(非虚函数是编译时静态解析,会出现静态绑定,虚函数是运行时动态解析,既然已经实现了多态,那么就会出现动态绑定,为了保证释放派生对象时能够按照正确的顺序调用析构函数,就得将其声明为虚函数)。

3、构造函数
①:若没有自定义构造函数,编译器会自动隐式声明一个默认无参构造函数,但是自己若定义了构造函数,那么隐式声明的默认无参构造函数便不存在,所以一般来说,习惯上,我们会先自己编写一个最基本的默认的无参构造函数,再继续编写适用于其它情况的构造函数,java中也是如此!

②:派生类的构造函数的实现要求调用基类的构造函数,若没有显示调用,那么就会暗中调用基类的默认无参构造函数,java也是如此!,java中基类的构造函数在子类构造函数中的调用要放在第一行,这也是因为沿袭C++中所谓的”顺序“而来

③:成员初始化列表(Member initialization List)和 成员逐一初始化(Memberwise Initialization)
成员初始化列表:
构造函数参数列表的括号外面加
:Xxx(…),Xxx(…)
中间由逗号隔开

③:成员逐一初始化:
涉及到拷贝构造函数(copy constructor)和拷贝赋值运算符函数(copy assignment operator)的知识
但我们设计class时,必须问问自己,在此class之上进行成员"逐一初始化"的行为模式是否适当?,如果答案肯定,我们就不需要另外提供拷贝构造函数(copy constructor),但如果答案是否定的,我们就必须另行定义拷贝构造函数(copy constructor),并在其中编写正确的初始化操作。

比如有类A,它的成员中有一个指向经过动态内存分配所形成的数组的指针,现在我们实例化类A的一个对象a,然后再声明一个 类A的对象b,令 b = a。现在暂时没有问题,但是当其中任一对象的析构函数调用的时候,对象中的那个指向经过动态内存分配所形成的数组的指针,必然是用不了,然而另外一个对象中的成员也是一个指向相同内存块的指针,肯定也用不了了,而你知道,对空间被释放的数组进行操作,是非常严重的事情,所以说这显然不符合正常伦理,我们也不想看到这样的事情发生,于是我们必须改变”成员逐一初始化“的行为模式,我们可以通过为类A提供另一个”copy constructor“来达到目的。

如果有必要为一个class编写拷贝构造函数(copy constructor),那么同样也有必要为它编写拷贝赋值运算符函数(copy assignment operator)。

总结:copy constructor适用于赋值运算符左边是已声明未实例化的对象,赋值运算符右边是已经实例化的对象。在其方法体中不需要判断赋值运算符左右两个对象是否相同。copy assignment operator适用于赋值运算符两边都是已经实例化的对象,所以需要在操作前要判断赋值运算符左右两个对象是否相同

另外我们更加提倡在constructor定义中,通过成员初始化列表来为每个类型参数进行初始化操作,而不是在constructor函数体中进行赋值操作。
这样虽然当参数类型是内置类型时,两者并无效率上的差异,但是当参数类型是一个class类型时就会出现高下之分。
为什么呢?因为,
constructor函数体内对参数的赋值操作有两步,(1)、先用默认构造函数来初始化赋值运算符左边的对象(2)、函数体内会以copy assignment operator将赋值运算符右边的对象复制给左边对象 。
constructor的member initialization list中将某类型参数初始化只需一步就能完成工作,(1)、以copy constructor 将赋值运算符右边对象赋值给左边对象。

构造函数不能是虚函数

4、基类的析构函数会在派生类的析构函数调用结束之后自动被调用,我们无需在派生类中对它做明确的调用操作



这篇关于C++学习笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程