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;
}
注意:使用了泛型后,就无法将声明和定义分离在两个文件了