【C++进阶知识】04 | 您所在的位置:网站首页 › 十分惆怅的意思是什么 › 【C++进阶知识】04 |
1. 函数默认实参
默认实参需要注意以下几点: (1)函数默认实参的赋值应从右往左,否则编译报错,因为参数入栈应该从右往左。 void f(int, int, int = 1); void f(int, int = 2, int); void f(int = 3, int, int);(2)类外的默认实参会使类的非默认构造函数变成默认构造函数。 class A { public: A(int a); void Print() { std::cout virtual ~F() { // 父类 } }; struct C : F { // 子类 }; /** * 对于p来说静态类型就是F * 对于p来说动态类型就是C * 所以如果父类和子类都有默认实参的话,会使用F中的默认实参函数 */ F* p = new C(); 2. 默认初始化默认初始化没什么难的,需要注意的是默认初始化是C++11新添加的,主要看一下位域初始化。 struct B { // int的低8位被初始化为12 int x : 8 = 12; // int的低8位被初始化为17 int y : 4 { 17 }; };在使用位域初始化的时候,一定要注意后面使用的运算符与:的优先级问题。 3 initializer_list 3.1 初始化列表的本质 #include std::initializer_list template class initializer_list { public: using value_type = _Elem; using reference = const _Elem&; using const_reference = const _Elem&; using size_type = size_t; using iterator = const _Elem*; using const_iterator = const _Elem*; constexpr initializer_list() noexcept : _First(nullptr), _Last(nullptr) {} constexpr initializer_list(const _Elem* _First_arg, const _Elem* _Last_arg) noexcept : _First(_First_arg), _Last(_Last_arg) {} _NODISCARD constexpr const _Elem* begin() const noexcept { return _First; } _NODISCARD constexpr const _Elem* end() const noexcept { return _Last; } _NODISCARD constexpr size_t size() const noexcept { return static_cast(_Last - _First); } private: const _Elem* _First; const _Elem* _Last; };可以看出initializer_list就是一个有begin和end的一片内存空间。 int x[] = { 1, 2, 3, 4, 5 }; std::vector v{1, 2, 3, 4, 5};相当于使用initializer_list{1, 2, 3, 4, 5},就是先构造了一个array{ 1, 2, 3, 4, 5 },再把首地址和尾地址赋给begin和end。 class A { public: /** 使用初始化列表构造并遍历 */ A(std::initializer_list list) { for (const int* item = list.begin(); item != list.end(); ++item) { std::cout int x; int y; int z; }; // 初始化列表构造,x=0,y=0,z=3 Point3D{.z = 3};虽然增加了指定初始化,但有很多的限定: (1)Point3D如果有了构造函数,则初始化列表会按照构造函数进行,指定的成员变量很有可能失败。 (2)指定初始化的顺序要按照定义顺序进行。 (3)联合体一次只能指定一个;指定初始化不能嵌套;指定初始化不能和普通的混用。 |
CopyRight 2018-2019 实验室设备网 版权所有 |