做网站北京,wordpress 谷歌分析,WordPress 跳转 xampp,中国建设劳动学会监制网站目录 初始化列表构造函数#xff1f;拷贝构造#xff1f;浅谈explicit关键字友元 内部类static成员总结 初始化列表
引入初始化列表#xff1a;简化代码#xff0c;提高效率 在编程中#xff0c;初始化列表是一种用于在创建对象时初始化成员变量的快捷方式。通过初始化列… 目录 初始化列表构造函数拷贝构造浅谈explicit关键字友元 内部类static成员总结 初始化列表
引入初始化列表简化代码提高效率 在编程中初始化列表是一种用于在创建对象时初始化成员变量的快捷方式。通过初始化列表可以在对象构造时直接为成员变量赋值而无需在构造函数体内进行赋值操作。这不仅使代码更简洁清晰还可以提高程序的执行效率。
在本文中我们将深入探讨初始化列表的概念及其在不同编程语言中的应用。我们将介绍初始化列表的语法结构并通过具体的示例代码演示如何在常见的编程语言中使用初始化列表。无论您是初学者还是有一定经验的开发者本文都将为您带来有价值的信息。
初始化列表的格式
class AA
{
public:AA(int n):_a(n),_b(n){}
private:int _a;int _b;
};d队列的初始化列表 MyQueue(int n,int rr):_pushst(n)//调用构造函数, _popst(n),_size(0){}注意 1、对于上面的初始化列表_pushst和_popst是自定义类型所以后面加个括号其实就是调用它的构造函数我们可以这样理解
2、如果我们要初始化const修饰的变量时只能在初始化列表中初始化因为const修饰的变量具有常性所以只能在初始化列表中初始化
3、当我们要初始化一个成员变量是引用时也必须在初始化列表中初始化
注意初始化列表是成员变量定义的地方而类中的成员变量只是成员变量的声明
如果我们不写初始化列表会生成初始化列表吗
答案是肯定的我们可以在成员变量声明的时候给一些缺省参数我们可以定义一个类然后用调试器进行调试在调试中我们可以发现我们进入这个类的时候会直接跳到缺省参数的那几行我们可以打开监视器进行观察也可以看见类中的成员就是用缺省值进行初始化的
构造函数拷贝构造
int main()
{AA a1(1);//构造函数AA a2 a1;//拷贝构造AA a3 1;//?return 0;
}第一个是构造函数第二个是拷贝构造那第三个是什么呢
第三个是隐式类型转换 在C语言中下面代码会生成一个临时变量
double b3.3;
int ab;对于上面代码会生成一个临时变量b先生成一个临时变量tmptmp是int类型然后tmp再赋值给a 所以回归正传刚刚我们用一个类等于一个数字其实是一个隐式类型转换本质是1先调用构造函数创建一个tmp的对象然后再利用tmp再拷贝拷贝构造给a3
如果用AAa3会报错因为1具有常性a3是tmp的引用a3可以修改但是因为常性不能修改所以会报错这里就是权限的放大所以我们可以在前面加一个const const AA a3 1;通过下面题目来引入一个初始化列表的规则
class A
{
public:A(int a):_a1(a),_a2(_a1){}void Print() {cout_a1 _a2endl;}
private:int _a2;int _a1;
};
int main() {A aa(1);aa.Print();
}A. 输出1 1B.程序崩溃C.编译不通过D.输出1 随机值对于上面这道题肯定不会选择A因为往往这种题都不可能这么直接更不可能选择B因为B是程序崩溃往往程序崩溃只会出现在野指针和空指针中只有从c和D中选肯定可以排除C因为不可能编译错误。
从上面的题目中我们就可以得到一个规则初始化列表的初始化顺序与初始化列表的顺序无关只与声明时的顺序有关
上面我们讨论的是只有一个参数的时候的初始化当有两个参数时我们应该如何传参呢
两个参数的参数列表的传参和数组类似
class AA
{
public:AA(int n 1, int m 2):_a(n), _b(n){}
private:int _a 1;int _b 0;
};
int main()
{AA a1(1);AA a2 a1;const AA a3 1;AA aa4 { 1,2 };return 0;
}当有两个参数的时候就可以利用C99的语法进行初始化其实等号也可以省略最好把等号加上
浅谈explicit关键字
前面我们谈了隐式类型转换如果我们不想进行隐式类型转换可以在函数前面加一个explicit关键字
智能指针是explicit关键字的使用场景
友元
友元函数就是全局函数只不过是写在了类中友元函数可以直接访问类中的私有成员变量下面我们简单的写一个友元函数作为示范 在声明中可以像下面这样声明 friend ostream operator(ostream out, const Date d);friend istream operator(istream in, Date d);一般情况下我们都会把友元函数的声明声明在类中的最前面声明完了之后友元函数在定义中还是像正常函数一样写前面不用加friend
友元的特性 友元关系是单向的不具有交换性。 比如上述Time类和Date类在Time类中声明Date类为其友元类那么可以在Date类中直接 访问Time类的私有成员变量但想在Time类中访问Date类中私有的成员变量则不行。友元关系不能传递 如果C是B的友元 B是A的友元则不能说明C时A的友元。友元关系不能继承在继承位置再给大家详细介绍。 出了友元函数还有友元类在友元类中我们可以用另一个类中的私有成员变量
下面是友元类的声明
class Time
{friend class Date; // 声明日期类为时间类的友元类则在日期类中就直接访问Time类
中的私有成员变量
public:Time(int hour 0, int minute 0, int second 0): _hour(hour), _minute(minute), _second(second){}private:int _hour;int _minute;int _second;
};
class Date
{
public:Date(int year 1900, int month 1, int day 1): _year(year), _month(month), _day(day){}void SetTimeOfDate(int hour, int minute, int second){// 直接访问时间类私有的成员变量_t._hour hour;_t._minute minute;_t._second second;}private:int _year;int _month;int _day;Time _t;
};内部类
内部类就是、一个类中定义另一个类 内部类的特性内部类是外部类的天生的友元类内部类可以随意访问外部类的成员变量
注意内部类也是一个单独的类唯一的区别是受到了外部类域的限制所以计算外部类的大小的时候不需要加上内部类的大小只需要算外部类的成员变量的大小即可
如果内部类定义在Public中则外面也可以访问如果内部类定义在private中则只有类的内部才能访问
static成员
我们来计算一下下面的类的大小
class BB
{
public:private:int _b1;static int _b1;
};注意成员变量不存函数和静态变量一个存放在代码区一个存放在静态区所以在计算类的大小的时候我们也不计算static修饰的成员变量
在C语言中我们知道static修饰的变量只初始化一次且在定义的时候初始化因为在类中的是声明所以我们不应该给成员变量缺省值也不应该将static修饰的成员变量放在初始化列表中进行初始化
正确的初始化方法如下
class BB
{
public:private:int _b1;static int _b1;
};
int BB::_b1 1;
int main()特性 静态成员为所有类对象所共享不属于某个具体的对象存放在静态区静态成员变量必须在类外定义定义时不添加static关键字类中只是声明类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问静态成员函数没有隐藏的this指针不能访问任何非静态成员静态成员也是类的成员受public、protected、private 访问限定符的限制 总结 通过本文的介绍我们深入探讨了几个编程中的关键概念友元、初始化列表、静态成员变量以及内部类。友元使得类之间的访问更加灵活但也需要慎重使用以保持封装性初始化列表能够简化对象的构造过程提高代码效率静态成员变量共享于类的所有对象是实现全局数据共享和类特性存储的有效方式内部类则可以在一个类的内部定义另一个类便于组织和封装相关的功能。 深入理解这些概念对于成为一名优秀的程序员至关重要。熟练掌握它们不仅可以提高代码的质量和效率还能够拓展我们的编程思维使我们更加灵活地应对不同的问题和挑战。 在实际编程中我们应该根据具体情况合理运用这些概念从而编写出清晰、高效且易于维护的代码。希望本文能够为您在编程学习和实践中提供一些帮助和启发。让我们继续不断学习和探索成为更加优秀的程序员