一:nullptr
空指针的定义:
int* p = nullptr;
int* p1 = NULL;
int* p2 = 0;
这3种方式都能把指针弄为空
对指针直接赋值是错误的
int* p;
int a = 0;
*p = a;//不能直接对指针赋值
NULL的方法是:
#define NULL 0 使用的是预处理
在文件#include<cstdlib>
nullptr 是c++新有的生成的空指针的方法:
nullptr 相当于常量
二:constexpr
constexpr来验证变量的值是否是常量表达式
声明为constexpr的变量一定是一个常量,而且必须要常量表达式初始化。
constexpr函数使用上的一些细节:
无参数函数初始化时:
constexpr int PN(){return 10;}
int main()
{
constexpr int k = PN();//用一个constexpr无参数函数初始化
return 0;
}
执行该初始化时,编译器把对constexpr函数的调用替换成结果值,为了在编译时能够展开,constexpr函数隐式的指定为内联函数。
有参函数初始化时:
constexpr不一定返回常量值:
- 当函数传一个常量时,返回值为常量
- 当函数传一个变量时,返回值为变量
//constexpr有参函数
constexpr int PN(int a)
{
return a;
}
int main()
{
//用一个constexpr有参函数初始化时,必须用一个常量来初始化
constexpr int k = PN(1);
int p=10;
constexpr int k = PN(p);//报错:p为变量不能初始化constexpr
int a=PN(p);
return 0;
}
constexpr构造函数:
构造函数不能为const,但可以为constexpr。
- constexpr构造函数可以声明成=default或者删除形式。
- constexpr构造函数体一般为空
- constexpr构造函数必须初始化所有数据成员
class RET
{
public:
constexpr RET(int x,double y,char z):a(x),b(y),c(z){}
//RET(int x, double y, char z):a(x),b(y),c(z){}
int a;
double b;
char c;
};
int main()
{
//生成一个constexpr对象
constexpr RET k(10,20.0,'p');
return 0;
}
三:类型别名
typedef 起别名的格式 :
typedef 数据类型 别名
using 起别名的格式:
using 别名=数据类型
typedef int p;//原有的起别名的方法
using g= char;//c++11新有的
四:类内初始化
c++11支持在类内初始化:
初始化时不能使用圆括号
class p
{
public:
int a = 0;
int* p = nullptr;
double k = 10.0;
int a[10] = {0};
int b(10);//报错
};
五:for的新用法
在C++11中,for循环有了一种新格式
for(变量 : 对象)//变量接收对象的值,但无法修改,只是可读
{
}
在数据类型后加&,这样的化可读可修改
for (auto& i : p)
{
}
vector<int>p;
p.push_back(5);
p.push_back(7);
p.push_back(9);
p.push_back(4);
p.push_back(3);
for (int i : p)
{
cout << i << endl;
}
六:begin()和end()标准函数
begin()和end()标准函数,和容器中的 begin()和end()不同,但作用相似。
begin()和end()标准函数:
用法:begin(对象) end(对象)
int a[10] = { 1,2,3,4,5,6,7 };
int* n = begin(a);//指向第一个元素地址
int* m = end(a);//指向最后一个元素的下一个元素
容器中的 begin()和end():
用法: 对象.begin() 对象.end()
vector<int>p{4,5,2,3,7};
vector<int>::iterator P = p.begin();//迭代器指向第一个元素
vector<int>::iterator P1 = p.end();//迭代器指向最后一个元素的下一个元素
七:含有可变形参的函数initislizer_list
initislizer_list是一种标准库类型,用于表示特定类型的值的数组
头文件为:#include<initializer_list>
常用的函数:
- size() 元素个数
- begin() 首元素指针
- end() 尾元素的下一个位置
initislizer_list的用法类似于vector,但initislizer_list存储的是常量值,无法修改。
int main()
{
initializer_list<int>p{ 1,2,3,4,5 };
auto n = p.begin();//类型为const int*
auto m = p.end();
while (n != m)
{
cout << *n <<" ";
n++;
}
return 0;
}
八:列表初始化返回值
c++11规定,函数可以返回花括号包围的值的列表。
数据类型:
- 普通类型:只能返回一个值
- 类:成员变量有多少个,就可以返回多少个
- 容器:可以返回多个,可以用于初始化
//普通类型
int text()
{
return { 1 };
}
//类
class person1
{
public:
int a;
int b;
person1(int i,int j):a(i),b(j){}
};
person1 text1()
{
return { 10,20 };//类里有多少个变量,就可以返回多少个
}
//容器
vector<int> text2()
{
return{1,2,3,4,5};//容器可以返回多个,可以用于初始化
}
int main()
{
vector<int>p(text2());//初始化
return 0;
}
九:=default的含义
在C++11中,如果需要默认行为,可以通过在参数列表后写上=default,要求编译器生成构造函数
=default在类中的位置:
- 在类中: 默认构造函数为内联函数
- 在类外:默认构造函数不为内联函数
class son
{
public:
son() = default;//默认为内联函数
};
class per
{
public:
per();
};
per::per() = default;//类外定义,默认不为内联函数
十:类数据成员的初始化
在C++11中,类开始需要默认值,则把默认值设置为一个类内初始化值。
class PK
{
public:
PK(int a,int b){}
int a;
int b;
};
class K
{
public:
vector<PK> P = { PK(1,2) };//在{}内调用构造函数
};
在提供一个类内初始值时,必须使用=或则花括号表示。