构造/析构函数

构造函数的类型

构造函数会在类每次实例化的时候自动调用,构造函数可以分成如下几类:

  • 按照是否有参数分为:无参构造函数和有参构造函数,其中无参构造函数也是默认的构造函数
  • 按照构造函数的类型分为:普通构造函数和拷贝构造函数

无参构造函数

#include <iostream>
#include <string>
using namespace std;

class test {
public:
    test() {
        cout << "test"<< endl; /* 实例化class test的时候自动调用 */
    }

    ~test() {}
};

int main(int argc, char const *argv[]) {
    test t; /* 会自动调用无参构造函数 */
    return 0;
}

有参构造函数

#include <iostream>
#include <string>
using namespace std;

class test {
public:
    test(int value) {
        cout << "test value: " << value << endl;
    }

    ~test() {}
};

int main(int argc, char const *argv[]) {
    /* 1.括号法 */
    test t1(1);

    /* 2.显示法 */
    test t2 = test(2);

    /* 3.隐式转换法 */
    test t3 = 3; /* 相当于:test t3 = test(3) */
    return 0;
}

拷贝构造函数

#include <iostream>
#include <string>
using namespace std;

class test {
public:
    /* 无参构造函数,为了测试创建一个无参构造函数 */
    test() {}

    /* 拷贝构造函数 */
    test(const test& t) {
        m_value = t.m_value;
    }

    ~test() {}

    int m_value;
};

int main(int argc, char const *argv[]) {
    test t;

    /* 1.括号法 */
    t.m_value = 1;
    test t1(t);
    cout << "t1.m_value: "<< t1.m_value << endl;

    /* 2.显示法 */
    t.m_value = 2;
    test t2 = test(t);
    cout << "t2.m_value: " << t2.m_value << endl;

    /* 3.隐式转换法 */
    t.m_value = 3;
    test t3 = t; /* 相当于:test t3 = test(t) */
    cout << "t3.m_value: " << t3.m_value << endl;
    return 0;
}

构造函数的规则

  • 默认情况下,编译器会为一个类定义三个函数,默认构造函数(无参数,空实现),默认析构函数(无参数,空实现),默认拷贝函数(浅拷贝,对属性值进行拷贝)
  • 如果用户定义了有参构造函数,那么编译器将不再定义默认的无参构造函数,但是会提供默认的拷贝函数
  • 如果用户定义了拷贝函数,那么编译器将不再提供其他构造函数

拷贝构造函数的深拷贝和浅拷贝

默认的拷贝构造函数,是直接进行最简单的赋值拷贝操作,如果出现了指针相关操作的话,会出现因为是简单赋值导致的重复释放的问题。示例如下:

#include <iostream>
#include <string>
using namespace std;

class test {
   public:
    /* 定义有参构造函数 */
    test(int value, int ptr_value) {
        m_value = value;
        m_ptr = new int(ptr_value);
    }

    /* 默认的拷贝构造函数,类似如下的代码,执行简单的赋值操作 */
    // test(const test& t) {
    //     m_value = t.m_value;
    //     m_ptr = t.m_ptr;
    // }

    /* 定义拷贝构造函数,执行深拷贝,就是重新new一片空间,用来存放m_ptr的值,与原class的地址就不会冲突了 */
    test(const test& t) {
        m_value = t.m_value;
        m_ptr = new int(*t.m_ptr);
    }

    ~test() {
        if (m_ptr != NULL) {
            delete m_ptr;
            m_ptr = NULL;
        }
    }

    int m_value;
    int* m_ptr;
};

void func() {
    /* 实例化test class,调用定义的有参构造函数 */
    test t1(10, 20);

    /* 实例化test class,没有定义拷贝构造函数的话调用默认拷贝构造函数,有定义则使用定义的拷贝构造函数 */
    test t2(t1);
}

int main(int argc, char const* argv[]) {
    func();
    return 0;
}

析构函数

析构函数主要进行资源的释放操作,如果类中没有需要手动释放的资源,可以保持空实现。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值