函数模板
template是定义泛型的关键字,T表示一种类型
typename关键字还有一个替身 class
函数模板声明和定义不能分开
cpp
template<typename T>
T add (T a,T b)
{
return a+b;
}
//template<typename T,typename E,typename K>
//template<class T>
函数模板的重载
调用时,指定不同的泛型(具体化,实例化)
每一次不同类型的调用就是一次函数重载的实例
cpp
template<class T1,class T2,class T3>
T3 add(T1 a,T2 b) { return a + b; }
int main()
{
cout << add<int, short, long>(1, 2) << endl;
cout << add<short, int, char>(41,7) << endl;
}
namespace名字空间
using naimespace std;//std空间中存在大量的标准函数、对象等(如果不写这个,就需要写 std:: )
定义语法
namespace 名称 { }
大括号里面可以写变量、函数、类等。
名字空间的作用
解决名字冲突的问题
cpp
double PI = 3.14;
double PI = 3.1415927;//重复定义是错的,C语言中可以
cpp
//正确的C++中的重复定义
namespace U1
{
double PI = 3.14;
void sendRedBag(int a){
return a+100;
}
}
namespace U2
{
double PI = 3.1415926;
void sendRedBag(int a){
return a+500;
}
}
int main()
{
//名字空间中的成员访问时:空间名字::成员名
//::域运算符
cout << "侄子来了:" << U1::sendRedBag(100) << endl;
cout << "外甥来了:" << U2::sendRedBag(100) << endl;
return 0;
}
名字空间中的成员访问时
空间名字::成员名
::域运算符
using 使用名字空间
1.using namespace 空间名称; // 引入指定的名字空间 【将空间中的成员展开到此处】
cpp
using namespace U1;
int main()
{
cout << "PI:" << PI << endl;
cout << "U1 PI:" << U2::PI << endl;
return 0;
}
2.using 空间名称::成员名; // 单个成员展开
cpp
using U1::sendRedBag;
int main()
{
cout << "PI:" << U1::PI << endl;
cout << sendRedBag(100) << endl;
return 0;
}
using用于类型别名,替换typedef
using 类型别名 = 旧(已有)类型
cpp
//以下两种都是定义类的新名称
typedef unsigned int uint;
using u32 = unsigned int;
int main()
{
uint a = 10;
u32 b = 20;
return 0;
}
注意
同一个名称的名字空间可以多次定义,编译时自动合并成一个,要避免空间中的成员多次定义。
cpp
namespace U1
{
double PI = 3.14;
void sendRedBag(int a){
return a+100;
}
}
namespace U2
{
double PI = 3.1415926;
void sendRedBag(int a){
return a+500;
}
}
namespace U1
{
int get(int a)
{
return a + 50;
}
}
int main()
{
cout << U1::sendRedBag(100) << endl;
cout << U1::get(50) << endl;
return 0;
}
动态内存管理
new和delect
动态内存(堆)管理的两个核心函数或关键字
new:用于在堆区申请空间初始化
delete:清理并释放堆空间
cpp
//C++
int main()
{
//new 数据类型(初始值)
//new申请堆空间时,不需要空间大小,一句数据类型,自动计算数据大小
int* p2 = new int (0);
*p2 = 100;
cout << *p2 << endl;
delete p2;
//创建连续10个int变量的连续空间大小
int* p3 = new int[10];//数组的创建
delete[]p3;//delete[]表示删除数组空间
//创建二维数组
//auto自动识别表达式的类型
int (*p4)[4] = new int[3][4];
delete[] p4;
return 0;
}
new
new的运算符
1.基于数据类型的创建与删除
2.基于数据类型的数组类型创建与删除
new函数
1.为运算符重载函数
2.基于new函数堆空间也可以使用delete函数删除
new的定位
1.创建的堆空间并未初始化
2.先new定位,再初始化
new和delete运算符重载
new
1.new关键字
cpp
int main()
{
//new 数据类型(初始值)
//new申请堆空间时,不需要空间大小,一句数据类型,自动计算数据大小
int* p2 = new int (0);
*p2 = 100;
cout << *p2 << endl;
delete p2;
//创建连续10个int变量的连续空间大小
int* p3 = new int[10];//数组的创建
delete[]p3;//delete[]表示删除数组空间
//创建二维数组
//auto自动识别表达式的类型
int (*p4)[4] = new int[3][4];
delete[] p4;
return 0;
}
2.new运算符函数
new能像malloc一样,一次声明多个变量空间
new(void*)
3.new定位函数
cpp
int main()
{
//new能像malloc一样,一次声明多个变量空间
int *p=(int*)operator new (sizeof(int) * 10);//运算符函数
//new(p) int(0);//单个空间初始化
new(p)int[10] {0};//所有元素置0;new(指针变量)定位(初始化)
p[0] = 1;
p[1] = 5;
cout << *(p + 1) << endl;
cout << *(p + 5) << endl;
//delete[] p;
operator delete(p) ;//运算符函数删除
}
在c中动态内存管理的函数有哪些?
malloc,free,calloc,realloc
C语言实现
cpp
//C语言
int main()
{
int* p1 = (int*)malloc(4);
if (p1 == NULL)
return -1;
memset(p1, 0, 4);
free(p1);
return 0;
}
C++实现
cpp
//C++
int main()
{
//new 数据类型(初始值)
//new申请堆空间时,不需要空间大小,一句数据类型,自动计算数据大小
int* p2 = new int (0);
*p2 = 100;
cout << *p2 << endl;
delete p2;
//创建连续10个int变量的连续空间大小
int* p3 = new int[10];//数组的创建
delete[]p3;//delete[]表示删除数组空间
//创建二维数组
//auto自动识别表达式的类型
int (*p4)[4] = new int[3][4];
delete[] p4;
return 0;
}
C++11新特性
auto
根据表达式来识别数据类型
cpp
int add(int a, int b)
{
return a + b;
}
int main()
{
auto a = 10;
auto b = 20 > 5 ? "good" : "Yes";//依据表达式的结果识别类型
auto p1 = &a;
//int(*pf)(int, int) = add;可以写成如下形式
auto p2 = add;//p2d的类型是:int(*)(int,int)
return 0;
}
不能用于函数的形参上
cpp
//是错的
int add(auto a, auto b)
{
return a + b;
}
decltype
根据表达式来识别数据类型,并使用此类型去定义变量。
可以用于函数的形参上
cpp
int add(int a, int b)
{
return a + b;
}
typedef decltype (&add) CallFun;
int sub(decltype(10) a, decltype(10) b,CallFun callfun)
{
return a - b;
}
int main()
{
auto a = 10;
auto b = 20 > 5 ? "good" : "Yes";//依据表达式的结果识别类型
auto p1 = &a;
//int(*pf)(int, int) = add;可以写成如下形式
auto p2 = add;//p2d的类型是:int(*)(int,int)
//decltype根据表达式来识别数据类型并使用此类型去定义变量
decltype("123")name{ "123" };
decltype(a * 10)x;
x = 0;
//decltype(add) f = add;//error
decltype(&add) f =add;
cout << f(10, 20);
return 0;
}
基于范围的for循环
1.增强for循环:(数据类型 变量名:数组名或STL容器){ }
每一次循环迭代,则会从数组或容器中提取一个成员,并赋值给变量。
auto可以用在增强for循环里
2.for中的变量名的类型可以使用auto自动推导
空指针
cpp
int main()
{
int x = 1, y = 2;
//在C++中使用NULL,对于重载的函数可能存在二义性
cout << add(NULL, 20) << endl;
// 为解决此问题,C++提供了空指针的运算符nullptr
cout << add(nullptr, 20) << endl;
return 0;
}