构造函数与析构函数

类内有两种特殊的函数(当然也要6种的说法,其中5种是构造函数),称为构造函数和析构函数,下面写了两个类来了解一下普通构造函数与析构函数。
代码地址:http://cpp.sh/27lkt

#include <iostream>

using namespace std;

class A {
public:
    A(int _m) : m(_m) { cout << "general construct A" << endl; }
    ~A() { cout << "desctruct A: " << this << endl; }
private:
    int m;
};

class B {
public:
    B() { cout << "general construct B" << endl; }
    B(double b) { cout << "general construct B double" << endl; }
    ~B() { cout << "destruct B: " << this << endl; }
};

A g_a(10);

int main()
{
    cout << "-------------------" << endl;
    //A a1;   // 匹配A::A()
    cout << "---------A a2(2)---------" << endl;
    A a2(2);
    cout << "---------A a3 = A(3)---------" << endl;
    A a3 = A(3);
    cout << "---------A* pa4 = new A(4)---------" << endl;
    A* pa4 = new A(4);
    
    // A* pa5 = new A[3];  // 匹配A::A()
    // A a6[3];          // 匹配A::A()
    cout << "---------A* pa7 = (A*)malloc(2)---------" << endl;
    A* pa7 = (A*)malloc(2);
    
    cout << "---------B b1---------" << endl;
    B b1;
    cout << "---------B b2()---------" << endl;
    B b2();
    cout << "-------- b1 = B()----------" << endl;
    b1 = B();
    cout << "---------B b3[2]---------" << endl;
    B b3[2];
    cout << "---------B *pb4 = new B---------" << endl;
    B *pb4 = new B;
    cout << "---------B *pb5 = new B()---------" << endl;
    B *pb5 = new B();
    cout << "---------B *pb6 = new B[3]---------" << endl;
    B *pb6 = new B[3];
    cout << "---------B *pb7 = (B*)malloc(10)--------" << endl;
    B *pb7 = (B*)malloc(10);
    cout << "---------B b8(5.0)------------------" << endl;
    B b8(5.0);
    cout << "--------------end------------------" << endl;
    
    return 0;
}

结果输出

general construct A
-------------------
---------A a2(2)---------
general construct A
---------A a3 = A(3)---------
general construct A
---------A* pa4 = new A(4)---------
general construct A
---------A* pa7 = (A*)malloc(2)---------
---------B b1---------
general construct B
---------B b2()---------
-------- b1 = B()----------
general construct B
destruct B: 0x75ecf0afd6af
---------B b3[2]---------
general construct B
general construct B
---------B *pb4 = new B---------
general construct B
---------B *pb5 = new B()---------
general construct B
---------B *pb6 = new B[3]---------
general construct B
general construct B
general construct B
---------B *pb7 = (B*)malloc(10)--------
---------B b8(5.0)------------------
general construct B double
--------------end------------------
destruct B: 0x75ecf0afd6af
destruct B: 0x75ecf0afd6b1
destruct B: 0x75ecf0afd6b0
destruct B: 0x75ecf0afd6ae
desctruct A: 0x75ecf0afd6d0
desctruct A: 0x75ecf0afd6c0
desctruct A: 0x601e14

从上面代码以及输出结果中,可以看出
1. 全局对象在进入main函数之前被创建。
g_a构造函数打印信息早于main函数内的打印信息

2. 调用含参构造函数的三种写法
A a2(2); // 直接构造
A a3 = A(3); // 在等号的右边创建:
A* pa4 = new A(4); // 通过new创建;

3. 调用含参构造函数的三种错误写法。
构造函数有参数时,不写参数就无法创建对象,下面的三种写法无法编译成功,原因在于他们指向的构造函数是A::A().
A a1;
A* pa5 = new A[3];
A a6[3];

4. new会调用构造函数,而malloc不会。
// A* pa5 = new A[3]; // 匹配A::A()
A* pa7 = (A*)malloc(2);
B *pb6 = new B[3];
B pb7 = (B)malloc(10);
对比上面四行代码的输出,可以知道new会去调用相应的构造函数,而malloc不会。因此pa5调用失败,因为找不到对应的构造函数,pa7与pb7调用后无信息打印,因为malloc仅仅只是申请了空间。

5. 调用无参构造函数六种情况。
B b1; // 无参构造,不写括号
b1 = B(); // 在等号左边构造
B b3[2]; // 在栈上创建数组
B* pb4 = new B; // 通过new创建,无括号
B* pb5 = new B(); // 通过new创建,有括号
B* pb6 = new B[3]; // 通过new在堆上创建
但是B b2并未调用构造函数是我未想到的,为什么呢?

6. 函数退出后会调用析构函数,释放在栈上创建的对象。
查看A调用析构函数的次数,可以看到,通过new创建的对象还在,析构函数的个数仅仅与栈和数据区有关,因此我们需要手动delete在堆上创建的对象

7. 先创建的对象后析构
上面的代码中先创建了一批A对象,再创建了一批B的对象,而析构时,先调用B类对象的析构函数,再调用A类对象的析构函数。

最后,再写一小段代码研究一下析构是在return之前还是return之后调用

int g_number = 10;

class D {
public:
    D() {}
    ~D() { 
        g_number = 5; 
        cout << "destruct D call" << endl;
    }
};

int func()
{
    D d;
    g_number = 100;
    return g_number;
}

int main()
{
    int x = func();
    cout << "x: " << x << endl;
    
    return 0;
}

结果输出为

destruct D call
x: 100

8. 析构函数在return之后调用
根据上面代码的例子,
若是析构在return之前调用,则应该 x: 5
若是析构在return之后调用,则应该 x: 100

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值