文章目录
目录
2.operator new与operator delete函数
前言
C++是一种通用编程语言,支持面向对象、过程性和泛型编程。在C++中,内存管理和模板是两个重要的概念,它们分别涉及到程序的运行时性能和代码的通用性。
一.内存管理
C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。
1.new delete操作符
对内置类型
比如
// 动态申请一个int类型的空间
int* ptr4 = new int;
// 动态申请一个int类型的空间并初始化为10
int* ptr5 = new int(10);
// 动态申请10个int类型的空间
int* ptr6 = new int[3];
delete ptr4;
delete ptr5;
delete[] ptr6;
注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用 new[]和delete[],两者不能混用
对自定义类型
C++的很多东西都是针对自定义类型实现的
比如这个
class A
{
public:
A()
{
cout<<"A()"<<endl;
}
~A()
{
cout<<"~A()"<<endl;
}
int a;
};
int main()
{
A* a=new A[3];
delete[] a;
}
在对自定义类型new时会自动调用类的构造函数,而delete会调用类的析构函数
2.operator new与operator delete函数
new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是 系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过 operator delete全局函数来释放空间。
这两个函数不会调用类构造函数和析构函数,比如
class A
{
public:
A()
{
cout<<"A()"<<endl;
}
~A()
{
cout<<"~A()"<<endl;
}
int a;
};
int main()
{
A* a=(A*)operator new(sizeof(A));
cout<<endl;
operator delete[](a);
}
3.定位new
定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象
比如
这样就显式调用了A的构造函数
然而构造函数不能直接显示调用,而析构函数却可以显式调用
定位new的用途不再这里,后面再细讲
二.模板
1.函数模板
函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定 类型版本。 函数模板格式 template 返回值类型 函数名(参数列表){}
注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)
比如这个交换函数
template<class T>
void swap(T&a,T&b)
{
T c=a;
a=b;
b=c;
}
int main()
{
int a=1,b=2;
char c='a',d='b';
swap<int>(a,b);
swap<char>(c,d);
cout<<a <<" "<<b<<endl;
cout<<c<<" "<<d<<endl;
}
2.类模板
定义格式
template<class T1, class T2, ..., class Tn>
class 类模板名
{
// 类内成员定义
};
类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<> 中即可,类模板名字不是真正的类,而实例化的结果才是真正的类,比如这个类
template<class TreeType>
class TreeNode
{
public:
TreeNode(TreeType x);
int Height();
~TreeNode();
void InOrder();
private:
TreeType _val;
int _height;
TreeNode<TreeType>* _left;
TreeNode<TreeType>* _right;
};