手表价格网站,直播带货系统,河口企业网站开发公司,网页传奇游戏单职业初始化列表#xff1a;
之前所说的构造函数初始化严格意义上来说不能叫变量初始化#xff0c;只能是称为赋初值#xff0c;C给出了初始化列表的概念
标准写法#xff1a;
class Date
{
public:Date (int year ,int month, int day):_year(year),_month(month),_day(day)…初始化列表
之前所说的构造函数初始化严格意义上来说不能叫变量初始化只能是称为赋初值C给出了初始化列表的概念
标准写法
class Date
{
public:Date (int year ,int month, int day):_year(year),_month(month),_day(day){}
private:int _year;int _month;int _day;
};以冒号开始逗号分隔
之所以要提出初始化列表的操作是因为有一些变量不得不在声明的时候给予初值如引用const变量、没有默认构造函数的自定义变量这三者如果不在声明的时候马上给予初值编译器将会报错。
易错点 观察下列代码
class A
{
public:A(int a):_a1(a),_a2(_a1){}
private:int _a2;int _a1;
};假设实例化一个A对象传值a1猜测一下输出_a1,_a2是什么你可能会认为是1 1其实不然对于初始化列表而言它不是从上到下一次初始化的而是根据变量声明的顺序初始化的显然_a2比_a1更早声明列表会优先初始化_a2,此时_a1还处于随机值的状态故最终的结果是输出 1 随机值.
正确的使用方式
① A a(1);//单参 A a(1,2); //多参 ② A a1; //单参 A a{1,2}; //多参 我们讨论一下第二种方式为什么正确编译器在此做了一个隐式类型转换将int类型的1转换成了A类型的变量存储在一个临时变量中接着临时变量将值传给a 说白了就是一次构造函数一次拷贝构造函数一些新版本的编译会在此将其优化成一次构造。
在构造函数前附加explicit关键字可以使第二种方式失效
匿名对象 正如C中结构体有匿名结构体一样C中对象也有匿名对象
//匿名对象
class A{……};
A();匿名对象的生命周期非常短只有当前所在的一行可以说是一次性用品。 之前所提到的隐式类型转化其实就是生成了一个匿名对象作为媒介完成的。
static成员
static的类成员称为类的静态成员用static修饰的成员变量称之为静态成员变量用static修饰的 成员函数称之为静态成员函数
在一些特定场景下我们在类中需要有静态成员变量和静态成员函数我们知道静态变量的声明周期是全局的仅可声明一次故可以推出类中的静态成员变量和函数不属于类中他们在类声明的时候就已经生成了实际空间。
因此在类中初始化static成员变量是会报错的static成员变量需要在类外定义
class B
{
private:static int _b;
};
int B::_b0;易错点
class C
{
public:static void Print(){cout_cendl;}
private:int _c1;
};上面的代码是错误原因是因为静态成员函数没有默认的this指针无法访问类中的元素但是既然没有this指针我们就可以不需要通过实际对象去调用类中的函数如
class C
{
public:static void Print(){coutCendl;}
};
int main(){C::Print();return 0;
}//这样是没有问题的友元函数
有些时候为了方便起见我们会想让外部函数可以访问类中的私有属性故C引入了友元函数使得这一目的得以实现
class Date
{
friend void Print(const Date para);
private:int _year2024;int _month1;int _day1;
};
int main(){Date d1;Print(d1);return 0;
}//可以通过友元函数不具有交换性A是B的友元不代表B是A的友元和传递性
————————————————————————————————————