温州建设监理协会网站,北京市门户网站建设,蝉知 wordpress,软件开发定制app1. 函数默认实参
默认实参需要注意以下几点#xff1a;
#xff08;1#xff09;函数默认实参的赋值应从右往左#xff0c;否则编译报错#xff0c;因为参数入栈应该从右往左。
void f(int, int, int 1);
void f(int, int 2, int);
void f(int 3, int, int);#x…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 i std::endl;}int i;
};
// 类外初始化默认实参
A::A(int a 100) : i(a) {}/** 在类外初始化非默认构造函数将其变为默认构造函数 */
A a A();
a.Print(); // 输出1003如果在类中添加了该函数的该参数的默认实参那么在类外再次定义该参数的默认实参会发生重定义错误。
4虚函数的默认实参将根据对象的静态类型编译时直接指定不会更改的类型确定。
struct F
{virtual ~F(){// 父类}
};struct C : F
{// 子类
};/**
* 对于p来说静态类型就是F
* 对于p来说动态类型就是C
* 所以如果父类和子类都有默认实参的话会使用F中的默认实参函数
*/
F* p new C();2. 默认初始化
默认初始化没什么难的需要注意的是默认初始化是C11新添加的主要看一下位域初始化。
struct B
{// int的低8位被初始化为12int x : 8 12;// int的低8位被初始化为17int y : 4 { 17 };
};在使用位域初始化的时候一定要注意后面使用的运算符与:的优先级问题。
3 initializer_list
3.1 初始化列表的本质
#include initializer_list
std::initializer_listtemplate class _Elem
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_castsize_t(_Last - _First);}private:const _Elem* _First;const _Elem* _Last;
};可以看出initializer_list就是一个有begin和end的一片内存空间。
int x[] { 1, 2, 3, 4, 5 };
std::vectorint 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_listint list){for (const int* item list.begin(); item ! list.end(); item){std::cout *item std::endl;}}
};初始化优先级
/** 调用构造5个元素每个元素都是5 */
std::vectorint x1(5, 5);
/** 调用构造2个元素5和5 */
std::vectorint x2{5, 5};3.2 隐式缩窄转换
隐式缩窄转换规则 1高位向低位转换如double向floatfloat向int。 2从整数类型向超过其最大值的类型转换如int a 999向char转换。
3.3 指定初始化
为了增加灵活性C20增加了指定初始化。
struct Point3D
{int x;int y;int z;
};
// 初始化列表构造x0y0z3
Point3D{.z 3};虽然增加了指定初始化但有很多的限定 1Point3D如果有了构造函数则初始化列表会按照构造函数进行指定的成员变量很有可能失败。 2指定初始化的顺序要按照定义顺序进行。 3联合体一次只能指定一个指定初始化不能嵌套指定初始化不能和普通的混用。