1、auto关键字
auto是C++11新增的自动变量,其原理是编译器根据上下文情况,确定组通变量的真正类型,并不是弱类型语言中的弱化变量。在真正的编程中建议尽量少使用auto,直接写出变量类型更加清晰易懂,在不知道变量类型或者冗长复杂的类型中可以考虑使用。
1.1 用于常用类型推导
int main()
{
auto var = 10;
auto str = "hello";
std::cout << "var:" << var << std::endl;
std::cout << "str:" << str << std::endl;
std::vector<std::string> vs;
for (auto i = vs.begin(); i != vs.end(); i++){
//..
}
}
1.2作为函数的返回值
auto add(int a, int b)
{
return a + b;
}
int main()
{
auto ret = add(1,2);
std::cout << " ret:" << ret << std::endl;
return 0;
}
auto在C++14中可以作为函数的返回值.
既然aoto可以作为函数的返回值,那么它是否可以作为类成员函数的返回值呢?答案是只能作为类内联函数的返回值;auto作为成员函数的返回值时,只能用于函数的定义,不能用于函数的声明,即用auto作为函数返回值时,需要把函数的实现写在头文件中,这样编译器可以根据函数实现的返回值确定auto的真实类型。
1.2 在定义模块函数时使用
template <typename _Tx, typename _Ty> void Multiply(_Tx x, _Ty y) { auto v = x*y; std::cout << v; } |
由于不知道模块传入类型,所以刚开始都不知道x*y的类型,需要使用auto类型了推导。
1.3 模块函数依赖于模板参数的返回值
template <typename _Tx, typename _Ty> auto multiply(_Tx x, _Ty y)->decltype(_Tx*_Ty) { return x*y; } |
当模块函数返回值依赖于模板参数时,依旧无法确定模板函数的类型,也就无法确定模板函数的类型,此时使用auto作为模板函数的返回值占位,它只是为函数的返回值占据一个位置,真正返回值是后面的decltype(_Tx*_Ty)。decltype用于查询表达式的数据类型,这里的类型(decltype(_Tx*_Ty))后置是因为如果写成正常的格式:decltype(_Tx*_Ty)multiply(_Tx x, _Ty y),这里的_Tx,_Ty还不知道是什么类型,会导致编译失败。
1.4 auto使用注意事项
1)auto变量必须在定义时初始化;
2)定义在同一个auto序列必须推导同一个种类型
auto a1 = 10, a2=10.5, a3=”hello” // 错误
3)如果初始化表达式是引用,则会把引用语义去除
int a = 1; int &b = a; auto c = b; //此时类型c没有引用语义,为int而非int&; auto &d = b;// 相当于auto时加上引用,此时为int& |
4)如果初始化表达式为const或volatile,则去除对应的特性
const int a = 1; auto b = a; //const特性不会保留,可以对b进行修改 const auto c = a; // auto时加入const,不能对c进行修改 //如果auto时需要保留const或volatile特性,则可以通道应用方式进行。如下: const int a2 = 2; auto &b2 = a2;//加上了&,故保留了const,不能对b2修改。 |
5)初始化数据时,auto推导为指针;若加入&,则推导类型为数组类型。
int a = 1; int a[3] = {1,2,3}; auto b = a; auto &c = a; std::cout << typeid(b).name << std::endl; std::cout << typeid(c).name << std::endl; 输出为: int * int[3] |
2、nullptr
为什么需要nullptr? NULL有什么毛病?
NULL在C++中就是代表着0,这是因为在C++中void* 类型是不允许隐式转换成其他类型的,所以C++中用0来代表空指针,但是在重载整形的情况下,会出现上述的问题。nullptr,可以保证在任何情况下都代表空指针,而不会出现上述的情况。
例:
class Test
{
public:
void test(int a)
{
std::cout << "test 1" << std::endl;
}
void test(int * a)
{
std::cout << "test 2" << std::endl;
}
};
int main()
{
Test test;
test.test(NULL);
test.test(nullptr);
}
运行结果:
test 1
test 2
NULL在c++里表示空指针,调用test.test(NULL),其实期望是调用的是void test(int * index),但结果调用了void test(int index)。但使用nullptr的时候,能调用到正确的函数。