博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
初始化列表,以及构造函数和析构函数的调用顺序
阅读量:3963 次
发布时间:2019-05-24

本文共 1819 字,大约阅读时间需要 6 分钟。

新学到了C++里新的初始化方法,初始化列表。因此来整理一下。若有错漏,还望指摘。

构造函数

构造函数可分为普通构造函数和拷贝构造函数。

  1. 普通构造函数

    构造函数就是在类实例化时,自动调用来生成类的函数。若未定义,则系统自动生成。比如:

    class test{
    };test A;

    在生成对象A的时候就会调用普通构造函数。

    形式为函数名与类名相同,没有也不能声明任何类型的返回值。

  2. 拷贝构造函数

    拷贝构造函数是在对类进行拷贝时,自动调用来根据已经实例化的对象来实例化一个新的对象的函数。若未定义则系统自动生成。

    比如:

    class test{
    };test A, B(A), C=A;

    在B和C构造的时候都会调用拷贝构造函数。

    此时值得注意的是,像C这样在最开始的声明中使用了赋值运算符进行拷贝的情况,虽然使用了赋值符号,但实际上调用的是拷贝构造函数,而不是重载的赋值运算符,而如下面的这种情况才会调用重载的赋值运算符:

    test A,C;C = A;

    (实际上也很好理解,第一种情况其实是在构造对象,第二种情况是构造好了之后的赋值,而赋值运算符并不是构造函数,所以在构造的时候虽然写的是赋值符号,但实际调用的是拷贝构造函数。)

    拷贝函数的形式是,函数名是类名,参数必须只有一个,是该类的引用或者指针,一般为该类的const引用,同样没有也不能声明任何类型的返回值。

初始化列表

构造过程其实分为初始化阶段与计算阶段。
对于类,可以用初始化列表来实现构造函数在初始化阶段直接赋初值。

class A{
public: A(int _x, int _y) : x(_x), y(_y) {
} //带初始化列表的普通构造函数 A(const A& a) : x(a.getX()), y(a.getY()) {
} //拷贝构造函数 int getX() const {
return x; } int getY() const {
return y; }private: const int x, y;};

初始化列表以冒号开始,形式为 变量名(初值),多个变量之间以逗号分隔。

初始化列表的用处在于,它可以对const修饰的常量进行初始化。而若写在大括号中,是在计算阶段赋值,而常量是不能在计算阶段进行赋值的。
初始化列表只能用于构造函数中,无论是普通构造函数还是拷贝构造函数。
成员变量中含有常量时,只能用初始化列表进行初始化。

注:最开始,我不知道此处可以直接读取引用a的private数据。因此以为必须用到封装函数来读取。而读取时又会报错,最后发现,必须将封装函数也设置为const才可以。而实际上可以直接 A(const A& a) : x(a.x), y(a.y) {} 这样实现。

后来我才明白,封装是针对类而言,而不是对象。因此定义在该类中的函数,哪怕不是构造函数,只要传入的参数是本类,就可以访问这个参数的私有成员变量。另外,友类也可以访问。

析构函数

析构函数是在销毁对象时,系统会自动调用的函数。如果未定义,系统会自动生成。
形式为波浪线~加上类名,同样没有也不能声明任何类型的返回值。比如:

classs test{
~test(){
}};

调用顺序:

如下的结构:

class A{
};class B{
};Class C : public A {
public: B a; B b;};int main(){
A *p = new C; delete p; p = nullptr;

那么main函数中在构造C的时候,先调用基类构造函数A(),然后是成员变量a的构造函数B(),然后是b的构造函数B(),最后是自身的构造函数C()。

但是在析构的时候,是根据指针来析构。如上面这个情况,因为p是A类指针,所以其实是只调用A的析构函数。若将p改为C类指针,则析构函数的调用顺序与构造函数相反,先是C本身的析构函数,然后是成员变量b的析构函数,然后是a,最后是基类的析构函数。若想析构顺序与指针无关,需要将析构函数定义为虚函数。

注:构造函数和析构函数只有用C++的new和delete才会被调用,如果用malloc和free,不会自动调用这两个函数

转载地址:http://uxxzi.baihongyu.com/

你可能感兴趣的文章
POJ3669---跳炸弹(广搜)
查看>>
POJ---1384Piggy-Bank (完全背包+装满问题)
查看>>
并查集基础知识
查看>>
POJ1182---食物链(带权并查集~技巧性超强的解法)
查看>>
POJ2492---A Bug's Life(做完食物链,再秒这个)
查看>>
POJ2063---Investment(完全背包)
查看>>
POJ1458---(最长公共子序列最基础题)
查看>>
POJ3356---(最长公共子序列)
查看>>
二叉树基础知识大全(核心理解遍历)
查看>>
03-树1 树的同构(25 分) 2017秋 数据结构 陈越、何钦铭
查看>>
04-树4 是否同一棵二叉搜索树(25 分)---陈越、何钦铭-数据结构-2017秋
查看>>
表达式求值(C实现,实现多括号,浮点数)---栈的实现以及运用。
查看>>
有序链表的合并(数据结构---单链表)
查看>>
栈实现(数据结构---数组,链表 C实现)
查看>>
POJ3903(dp,最长上升子序列,最基础题)
查看>>
POJ1836-Alignment(最长上升子序列)
查看>>
POJ 1251 Jungle Roads(最小生成树简单题)
查看>>
HDU 1690---Bus System(Floyd模板题+合理定义INF)
查看>>
POJ 2240---Arbitrage(Floyd的dp思想)
查看>>
Dijkstra算法---模板
查看>>