本部分介绍了c++11的崭新的类型推导、循环、模板和构造方法。
弃用的特性
1. 不允许以下赋值出现,应使用const char *
后者auto
。
1
|
char *str = "hello world!";
|
2. C语言风格的类型转换被弃用,应该使用 static_cast
、reinterpret_cast
、const_cast
来进行类型转换
3. register
, auto_ptr
关键字被弃用。
语言增强
新的关键字
-
使用nullptr
而不是NULL
。新的nullptr
为nullptr_t
类型,可以隐式转换为任何类型,同时避免了NULL == 0
这种类型冲突。
-
constexpr
函数:告诉编译器返回的值为常量表达式
类型推导
auto类型
- auto型可以作为变量的声明类型,函数的返回类型
- auto型作为函数参数在c++17中才可使用,但要注意重载的问题
- auto不能用于数组的类型推导
迭代器的样例:
1
|
for(auto itr = vec.cbegin(); itr != vec.cend(); ++itr);
|
decltype函数
返回值为一个类型。比如我们可以把z声明为推测的类型
1
|
decltype(x+y) z = x + y;
|
for(item:array)循环
像Python一样地迭代:
1
2
3
4
5
|
std::vector<int> arr(5, 100);
// & 启用了引用, 如果没有则对 arr 中的元素只能读取不能修改
for(auto &i : arr) {
std::cout << i << std::endl;
}
|
初始化列表
除了
- 拷贝构造
- () 构造函数初始化
加入了使用列表来初始化的特性:
1
2
3
4
5
6
7
|
class Magic {
public:
Magic(std::initializer_list<int> list) {}
};
Magic magic = {1,2,3,4,5};
std::vector<int> v = {1, 2, 3, 4};
|
模板的强化
关键字
- 外部模板
extern template
推迟模板的实例化
>>
不再只是右移运算符,可以视作括号嵌套:
1
|
std::vector<std::vector<int>> wow;
|
using提供的类型别名
using提供了以下的别名:
- 函数指针作为新类型
- 模板类型作为新类型
1
2
3
4
5
6
|
typedef int (*func)(int *); // 定义了一个返回类型为 int,参数为 int* 的函数指针类型,名字叫做 func
using func = int (*)(int *); // 同上, 更加直观
template <typename T>
using IntVec = std::vector<int>; // 合法
IntVec v;
|
默认模板类型
比如直接使用以下模板函数就可以不指定模板参数直接使用add:
1
2
3
4
|
template<typename T = int, typename U = int>
auto add(T x, U y) -> decltype(x+y) {
return x+y;
}
|
变长参数模板
1
2
|
template<typename... Ts> class Magic; //任意数量参数
template<typename Require, typename... Args> class Magic; //一个以上参数
|
OO的增强
委托构造
委托本类的其他构造函数构造
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
class Base {
public:
int value1;
int value2;
Base() {
value1 = 1;
}
Base(int value) : Base() { // 委托 Base() 构造函数
value2 = 2;
}
};
int main() {
Base b(2);
std::cout << b.value1 << std::endl;
std::cout << b.value2 << std::endl;
}
|
继承构造
在子类中使用父类的构造函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
class Base {
public:
int value1;
int value2;
Base() {
value1 = 1;
}
Base(int value) : Base() { // 委托 Base() 构造函数
value2 = 2;
}
};
class Subclass : public Base {
public:
int value3;
Subclass(int value3, int value2) : Base(value2) { // 继承父类构造
this->value3 = value3;
}
};
int main() {
Subclass s(3,2);
std::cout << s.value1 << std::endl;
std::cout << s.value2 << std::endl;
std::cout << s.value3 << std::endl;
}
|
显式虚函数重载
- 当重载虚函数时,引入
override
关键字将显式的告知编译器进行重载,编译器将检查基函数是否存在这样的虚函数,否则将无法通过编译
final
则是为了防止类被继续继承以及终止虚函数继续重载引入的。
强类型枚举
类型安全的枚举类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
enum class new_enum : unsigned int {
value1,
value2,
value3 = 100,
value4 = 100
};
// 内部可以比较
if (new_enum::value3 == new_enum::value4) {
std::cout << "new_enum::value3 EQ new_enum::value4" << std::endl;
}
//重载 >>
template<typename T>
std::ostream& operator<<(typename std::enable_if<std::is_enum<T>::value, std::ostream>::type& stream, const T& e)
{
return stream << static_cast<typename std::underlying_type<T>::type>(e);
}
//就可以直接输出
std::cout << new_enum::value3 << std::endl
|