auto关键字
在C语言中,auto 用来声明一个存储在栈的变量,因此它只能用来修饰临时变量,不能用来修饰全
局变量、静态变量,与此同时临时变量本身默认就是存储在栈中,因此在C语言中,auto 基本上是作废
的。
在C++中,auto 代表自动获得数据的类型,比如:
auto a = 100; // 等价于: int a = 100;当然,上述代码仅是语法示例,无法体现 auto 的价值,在C++的函数模板、类模板中,利用 auto 自动获得数据类型,往往有奇效,例如:
// 以下函数是一个模板,接收一个类型为 T 的容器
// 注意:类型 T 是动态的,可变的,不定的。
template <typename T>
void show(T &container)
{
// 利用 auto 动态获取未知类型容器的相关数据
auto it = container.begin();
...
... }使用auto 关键字可以对具体的类型进行模糊(泛化),如果某一个功能的操作流程式固定,唯一的不同在于数据的类型,这时候就可以简单地使用auto关键字对类型进行模糊的操作:
#include <iostream>
2
3 using std::cout ;
4 using std::endl ;
5 using std::string ;
6
7 // 通过auto简单粗暴地模糊数据的类型
8 // 让该函数可以接收任意类型的参数传递
9 auto Add( auto a , auto b )
10 {
11 return a + b ;
12 }
13
14 int main(int argc, char const *argv[])
15 {
16 int Num = Add( 123 , 567 );
17
cout << Num << endl;
18
19 float Num2 = Add( 123.333 , 567.222 );
20
cout << Num2 << endl ;
21
22
string s1 = "Hello";
23
string s2 = "World";
24 auto str = Add( s1 , s2 );
25
cout << str << endl ;
26
27 return 0;28 }函数默认参数
与c不同,c++允许给函数传递默认参数
例如:
float ConeVolume(float r,float h = 1)
{
return (M_PI*r*r*h)/3;
}
int main() {
//调用时不传默认参数 默认为1
float volume1 = ConeVolume(2);
cout << "volume1: " << volume1 << endl;
//传入参数,替代默认参数
float volume2 = ConeVolume(2,2);
cout << "volume2: " << volume2 << endl;
return 0;
}注意:
为了防止出现二义性,具备默认值的参数只能位于参数列表的最右边
如果函数定义与函数声明不在同一文件,一般只为声明指定默认参数,定义处不写默认参数。
函数重载
这也是c没有的特性,在c语言中,同作用域内的同名函数编译会报错重定义。
C++中,重名函数只要满足一定的要求,可以同时存在,这大大拓展了函数设计的灵活性。这种重名且可并存的语法机制,被称为函数重载。
例如string的构造函数有以下重载形式,根据传入参数的不同来调用不同的重载函数
1 string ( const string& str );
2 string ( const string& str, size_t pos, size_t n = npos );
3 string ( const char * s, size_t n );
4 string ( const char * s );5 string ( size_t n, char c )可以构成函数重载的情况
- 参数个数不同
- 参数类型不同
- 参数顺序不同
- 类方法(类内部的函数)的
const属性可以构成重载 - 普通指针与常量指针可以构成重载
不可以构成函数重载的情况
- 函数名,参数列表完全一致。
- 函数返回值类型差异。
- 静态函数声明。
- const型变量(包括指针常量)。
引用类型的参数是否可以形成重载,要根据实参的具体情况来定:
如果实参为常量,那么可以重载。
如果实参为变量,那么不可以重载
void f(int a);
void f(int &a);
int main()
{
int m = 100;
// ×: 会引起二义性,两个版本都能跟参数完全匹配
f(m);
// √: 可以顺利调用,因为普通引用类型无法指向常量
f(6); }枚举循环
从C++11开始,C++对for语句引入了枚举循环的概念,专用于具有确定元素个数的数组、容器或集 合,带来更加方便的操作,下面是一个简单的示例代码
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
int a[3] = {1,2,3};
// 枚举数组a中的各个元素,并输出它们8
for(int i : a)
cout << i << endl;
return 0;
}可以看到枚举for循环的语法非常简单,在上述代码中,i 的类型与待枚举的数组 a 的元素类型一 致,循环的过程就是让变量 i 逐个取得数组 a 中的各个元素,很显然,循环次数不再由程序代码指定, 而是由待枚举的数据的元素个数决定。
堆内存管理
在c中,有malloc和calloc,free来进行堆内存的管理
在c++中,新增了new和delete来进行管理
nt main(void)
{
// 申请一块int型数据大小的堆内存
int *p1 = new int;
int *pp1 = malloc(sizeof(int)) ;
// 申请一块可以存储100个int型数据大小的堆内存
int *p2 = new int[100];
int * pp2 = calloc(100 , sizof(int)) ;
// 申请一块35个字节大小的堆内存
char *p3 = new char[35];
char * pp2 = calloc(35 , sizof(char)) ;
// 释放所有的堆内存资源15
delete p1;
delete [] p2;
delete [] p3;
free(pp1);
free(pp2);
free(pp3);
}注意:在使用delete时,释放连续内存块需要加上 []
申请类类型的内存时,new 会自动调用类的构造函数,而 malloc() / calloc() 不会。
释放类类型的内存时,delete 会自动调用类的析构函数,而 free() 不会


