C++内存管理与模版

1.编译器对对象拷贝时的优化

        在面对连续拷贝时,编译器会根据情况,对代码进行优化,如下面这段代码:

#include<iostream>
using namespace std;




struct Data
{
    Data(int n = 10)
    {
        _a = n;
        cout << "调用构造" << endl;
    }

    Data(const Data& d)
    {
        _a = d._a;
        cout << "调用拷贝构造" << endl;
    }


    void print()
    {
        cout << _a << endl;
    }


    int _a;


    ~Data()
    {
        cout << "调用析构" << endl;
    }


};

Data Creat()
{
    Data d(20);

    return d;
}


int main()
{
    Creat().print();

    return 0;
}

在VS2019这个编译器下,debug模式中调用了一次构造和一次拷贝,而在release下优化为了仅有一次构造:

Debug :

Release:

2.new/delete

        在C++中,有了一种代替malloc/free函数来动态向堆申请释放空间的操作符,即new/delet操作符:

#include<iostream>
using namespace std;




struct Data
{
    Data(int n = 10)
    {
        _a = n;
        cout << "调用构造" << endl;
    }

    Data(const Data& d)
    {
        _a = d._a;
        cout << "调用拷贝构造" << endl;
    }


    void print()
    {
        cout << _a << endl;
    }


    int _a;


    ~Data()
    {
        cout << "调用析构" << endl;
    }


};



int main()
{
    //使用new操作符创建对象
    Data* d1 = new Data(20);
    //多个对象使用new 类名[对象个数]{初始化对象1,初始化对象2,......}创建
    Data* d2s = new Data[10]{Data(20),Data(20)};


    //记得使用delete操作符删除对象,多个对象用delete[]
    delete d1;
    delete[] d2s;
    return 0;
}

        与malloc/free不同的是,malloc申请内存失败时返回的是null,需要判空,而new则不需要,但它要捕获异常,malloc无法完成对自定义类型对象的初始化,而new可以,malloc/free在创建和销毁对象时,不会调用构造和析构函数,而new/delete可以,可以认为,new/delete是为了适应类和对象的需要,对malloc/free进行的升级

        注意:在使用时,一定不要乱搭配,比如new要和delete搭配,new[]要和delete[]搭配,不然就会出现一堆莫名其妙的bug!(别问我怎么知道的qwq)

3.类和函数的模版

        使用template来为函数或类创建不针对某一类型的泛用类型,用于减少同一操作函数的重写,其具体用法如下:

//使用template<typename 类型名1,typename 类型名2,......>来创建类型模版
template<typename T1 ,typename T2>
T1 add(T1 a, T2 b)
{

    return a + b;
}



template<typename T1>
struct Data
{
    Data(int n = 10)
    {
        _a = n;
        cout << "调用构造" << endl;
    }

    Data(const Data& d)
    {
        _a = d._a;
        cout << "调用拷贝构造" << endl;
    }


    void print()
    {
        cout << _a << endl;
    }


    int _a;
    T1 _b;

    ~Data()
    {
        cout << "调用析构" << endl;
    }


};



int main()
{
    cout << add(2.3, 1)<< endl;

    //使用时建议用函数名<类型1,类型2......>来明确类型
    cout << add<double,int>(2.3, 1) << endl;


    return 0;
}

注意:使用了泛型后,就无法将声明和定义分离在两个文件了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值