咋么做网站,网站建站域名解析最后做,html5网站素材,手表商城网站建设构造函数中的初始化列表
之前在实现构造函数时#xff0c;主要是在函数体内进行赋值#xff0c;而构造函数还有另一种初始化方式#xff0c;通过初始化列表进行初始化。
初始化列表的使⽤⽅式是以⼀个冒号开始#xff0c;接着是⼀个以逗号分隔的数据成员列表#xff0c;…构造函数中的初始化列表
之前在实现构造函数时主要是在函数体内进行赋值而构造函数还有另一种初始化方式通过初始化列表进行初始化。
初始化列表的使⽤⽅式是以⼀个冒号开始接着是⼀个以逗号分隔的数据成员列表每个成员变量后⾯跟⼀个放在括号中的初始值或表达式。每个成员变量在初始化列表中只能出现⼀次语法理解上初始化列表可以认为是每个成员变量定义初始化的地⽅。
要注意的是初始化列表中按照成员变量在类中声明顺序进行初始化跟成员在初始化列表出现的的先后顺序是无关的。但一般建议声明顺序和初始化列表顺序保持⼀致。
#includeiostreamclass Date
{
public:Date(int year 1, int month 1, int day 1):_year(year), _month(month), _day(day){}void Print(){std::cout _year - _month - _day std::endl;}private:int _year;int _month;int _day;
};int main()
{Date d1(2024, 7, 20);d1.Print();return 0;
}
要区分函数参数中给的缺省值并不能初始化成员变量。两者是不同的东西要加一区分。
#includeiostreamclass Date
{
public:Date(int year 1, int month 1, int day 1):_year(year), _month(month){}void Print(){std::cout _year / _month / _day std::endl;}private:int _year;int _month;int _day;
};int main()
{Date d1(2024, 7, 20);d1.Print();return 0;
}
这里 _day 并未初始化为随机值。
#includeiostreamclass Date
{
public:Date(int year 1, int month 1, int day 1):_year(year), _month(month){// _day未在初始化列表中初始化在函数体内也能初始化如果都没有就为随机值_day day;}void Print(){std::cout _year / _month / _day std::endl;}private:int _year;int _month;int _day;
};int main()
{Date d1(2024, 7, 20);d1.Print();return 0;
}
构造函数在初始化时会先走初始化列表进行初始化若初始化列表没有初始化再走构造函数内部看是否初始化若都没有就只能要看编译器是否初始化但一般都为随机值。
一般的内置类型的成员普通的构造函数就可以实现不需要初始化列表。但有些成员变量只能通过初始化列表进行初始化。
前面说过初始化列表可以认为是每个成员变量定义初始化的地方而有些变量只能在定义的时候进行初始化如
// const常量只能在定义时初始化一次
const int a 1;
//引用也只能在初始化时定义
int x 10;
int y x;
还有一个没有默认构造的类类型变量。如 该默认构造无需传参其初始化时若无参数则会使用缺省值故可完成初始化。但如果没有缺省值则程序会编译出错。
#includeiostreamclass A
{
public:A(int a):_a(a){std::cout A() std::endl;}private:int _a;
};class Date
{
public:Date(int xx, int year 1, int month 1, int day 1):_year(year), _month(month),_day(day),a(1),x(xx){}void Print(){std::cout _year / _month / _day std::endl;}private:int _year;int _month;int _day;const int a;int x;A y;
};int main()
{int x 1;Date d1(x, 2024, 7, 20);return 0;
}
其编译会报错 这里必须要传入参数所以我们就需要在初始化列表进行初始化。
#includeiostreamclass A
{
public:A(int a):_a(a){std::cout A() std::endl;}private:int _a;
};class Date
{
public:Date(int xx, int year 1, int month 1, int day 1):_year(year), _month(month),_day(day),a(1),x(xx),y(1){}void Print(){std::cout _year / _month / _day std::endl;}private:int _year;int _month;int _day;const int a;int x;A y;
};int main()
{int x 1;Date d1(x, 2024, 7, 20);return 0;
}
此外C11⽀持在成员变量声明的位置给缺省值这个缺省值主要是给没有显示在初始化列表初始化的成员使⽤的。
#includeiostreamclass A
{
public:A(int a):_a(a){std::cout A() std::endl;}private:int _a;
};class Date
{
public:Date(int xx, int year 1, int month 1, int day 1):_year(year), _month(month),_day(day),x(xx){}void Print(){std::cout _year / _month / _day std::endl;}private:int _year;int _month;int _day;const int a 1;int x;A y 1;
};int main()
{int x 1;Date d1(x, 2024, 7, 20);return 0;
}
但尽量使⽤初始化列表初始化因为那些你不在初始化列表初始化的成员也会⾛初始化列表如果这 个成员在声明位置给了缺省值初始化列表会用这个缺省值初始化。
但如果没有给缺省值对于没有显示在初始化列表初始化的内置类型成员是否初始化取决于编译器C并没有规定。对于没有显示在初始化列表初始化的自定义类型成员会调用这个成员类型的默认构造函数如果没有默认构造会编译错误。所以尽量使用初始化列表。 类型转换
举最简单的例子来说
#includeiostreamint main()
{int a 10;double b a;return 0;
}
这是一个简单的类型转换。 C⽀持内置类型隐式类型转换为类类型对象但需要有相关内置类型为参数的构造函数。
#includeiostreamclass A
{
public://构造函数A(int a){_a a;}void Print(){std::cout _a std::endl;}
private:int _a;
};int main()
{// 6构造⼀个A的临时对象再用这个临时对象拷贝构造a1// 但若编译器遇到连续构造拷贝构造就会优化为直接构造A a1 6;a1.Print();//这个隐式类型转换过程为//构造函数A a2(1);//拷贝构造注该类只有内置类型的成员变量编译器自动生成的拷贝构造就能实现目的A a3 a2;//所以就直接通过隐式类型转换来使用return 0;
}
在C11之前其是不支持多参数转化一些较老的编译器就不支持多参数转化。
#includeiostreamclass A
{
public://构造函数A(int a1 1, int a2 2){_a1 a1;_a2 a2;}void Print(){std::cout _a1 _a2 std::endl;}private:int _a1;int _a2;
};int main()
{A a { 6,66 };a.Print();//相当于A a1(1, 11);A a2 a1;a2.Print();return 0;
}
构造函数前⾯加关键字 explicit 就可以不再⽀持隐式类型转换。 static成员
⽤static修饰的成员变量称之为静态成员变量静态成员变量⼀定要在类外进⾏初始化。其为所有类对象所共享不属于某个具体的对象不存在对象中存放在静态区。
#includeiostreamclass A
{
public:private:int a;static int b;
};//在类外初始化静态成员变量
int A::b 1;int main()
{return 0;
}
而⽤static修饰的成员函数称之为静态成员函数静态成员函数是没有this指针的。静态成员函数可以访问其他的静态成员但是不能访问⾮静态的因为没有this指针。但⾮静态的成员函数可以访问任意的静态成员变量和静态成员函数。 #includeiostreamclass A
{
public:static int Get(){return b;}void func(){std::cout a b std::endl;}private:int a 1;static int b;
};//在类外初始化静态成员变量
int A::b 1;int main()
{A a;a.func();return 0;
}
一定要注意静态成员变量不能在声明位置给缺省值初始化因为缺省值是个构造函数初始化列表的静态成员变量不属于某个对象不⾛构造函数初始化列表。
由于静态成员也是类的成员所以其受public、protected、private等访问限定符和类域的限制。