c++ 类和对象 —— 下 【复习总结】

打印 上一主题 下一主题

主题 962|帖子 962|积分 2886

1. 深入构造函数

1.1 函数体赋值

前文我们提到,创建对象时,编译器会调用构造函数给成员变量赋值。但这并不能称为对对象中成员变量的初始化。由于初始化只能初始化一次,但构造函数体内可以多次赋值。构造函数体中语句只能称为赋初值
那么,成员变量初始化的地方在那里?我们不得不引入一个知识:初始化列表
1.2 初始化列表

初始化列表:冒号开始,接着是逗号分隔成员列表,每个“成员变量”后跟一个放括号中的初始值或表达式
  1. class Date
  2. {
  3. private:
  4.         int _year;
  5.         int _month;
  6.         int _day;
  7. public:
  8.         Date(int year, int month, int day)
  9.                 //初始列表
  10.                 :_year(year)
  11.                 ,_month(month)
  12.                 ,_day(day)
  13.            //函数体赋值
  14.            {}
  15. };
复制代码
留意事项:
1. 每个成员变量在初始化列表最多出现一次(即只能初始化一次)
2. 类中包罗:a.引用成员变量 b.const成员变量 c. 自界说成员函数(且该类没有默认构造函数)
(a 和 b 是由于要求在界说时必须初始化;c 是由于会主动调用它的默认构造函数)
3. 只管使用初始化列表初始化,对于自界说类型成员变量,一定会先使用初始化列表初始化
4. 成员变量在类中声明次序是其在初始化列表中的初始化次序,和它在初始化列表的先后次序无关
  1. class A
  2. {
  3. private:
  4.         int _a;
  5. public:
  6.         A(int a)
  7.                 : _a(a)
  8.         {}
  9. };
  10. class B
  11. {
  12. private:
  13.         A _ao;   //没有默认构造函数
  14.         int& _ret; //引用
  15.         const int _n; //const
  16. public:
  17.         B(int a, int ret)
  18.                 :_ao(a)
  19.                 ,_ret(ret)
  20.                 ,_n(10)
  21.         {}
  22. };
复制代码
1.3 explicit关键字

对于担当单个参数的构造函数,还有类型转换的作用。
担当单个参数的构造函数:
1. 构造函数只有一个参数
2. 构造函数有多个参数,除第一个参数没默认值,其他参数都有默认值
3 .全缺省构造函数
但用explicit修饰构造函数,会克制构造函数的隐式转换
  1. class Date
  2. {
  3. private:
  4.         int _year;
  5.         int _month;
  6.         int _day;
  7. public:
  8.         //单参数构造函数,有类型转换的作用
  9.         //用explicit修饰,禁止类型转换
  10.         explicit Date(int year)
  11.                 :_year(year)
  12.         {}
  13.         //有两个缺省参数,相当于单个参数
  14.         explicit Date(int year, int month=1, int day=1)
  15.                 :_year(year)
  16.                 ,_month(month)
  17.                 ,_day(day)
  18.                 {}
  19. };
复制代码
2. static成员

声明为static的类成员为类的静态成员,修饰成员变量称为静态成员变量;修饰成员函数称为静态成员函数。静态成员变量必须在类外初始化
特性:
1. 静态成员为所有类对象共享,存放在静态区
2. 静态成员变量必须在类外界说,类中只是声明,界说不加static关键字
3. 静态成员用 类名::静态成员 或者 对象.静态成员 访问
4. 静态成员函数没有隐蔽的this指针,不能访问任何非静态成员
5.静态成员也是类的成员,受到访问限定符的限制
3. 友元

友元可以突破类封装的限制。但友元会增长耦合度,粉碎封装,不宜多用
友元:友元函数友元类
3.1 友元函数

友元函数可以直接访问类的私有成员,它是界说在类外部的普通函数,需要在类的内部声明,声明时要加friend关键字
留意事项:
1. 友元函数不是类的成员函数,只是可以访问类的私有和掩护成员
2. 友元函数不能用const修饰
3. 友元函数可以在类界说的任何位置声明,不受访问限定符的限制
4. 一个函数可以是多个函数的友元函数
5. 友元函数的调用和普通函数调用相同
实用场景:
  1. //如果想重载operator<<,但无法重载为类成员函数。
  2. //this指针默认是第一个参数也就是左操作数了。
  3. //但是实际使用中cout需要是第一个形参对象,所以要将operator << 重载成全局函数。
  4. // 但类外没办法访问成员,此时就需要友元来解决。operator >> 同理
  5. class Date
  6. {
  7.     friend ostream& operator<<(ostream& _cout, const Date& d);
  8.     friend istream& operator>>(istream& _cin, Date& d);
  9. public:
  10.     Date(int year = 2025, int month = 1, int day = 1)
  11.         : _year(year)
  12.         , _month(month)
  13.         , _day(day)
  14.     {}
  15. private:
  16.     int _year;
  17.     int _month;
  18.     int _day;
  19. };
  20. ostream& operator<<(ostream& _cout, const Date& d)
  21. {
  22.     _cout << d._year << "-" << d._month << "-" << d._day;
  23.     return _cout;
  24. }
  25. istream& operator>>(istream& _cin, Date& d)
  26. {
  27.     _cin >> d._year;
  28.     _cin >> d._month;
  29.     _cin >> d._day;
  30.     return _cin;
  31. }
复制代码
3.2 友元类

友元类的所有成员函数都可以是另一个类的友元函数,可以访问另一个类的成员
留意事项:
1. 友元关系单向,不具有交互性
2. 友元关系不能转达
3. 友元关系不能继承
  1. class Time
  2. {
  3. //声明日期类为时间类的友元类,在日期类中可以直接访问Time类的私有成员变量
  4. friend class Date;
  5. public:
  6.     Time(int hour = 0, int minute = 0, int second = 0)
  7.         : _hour(hour)
  8.         , _minute(minute)
  9.         , _second(second)
  10.     {}
  11. private:
  12.     int _hour;
  13.     int _minute;
  14.     int _second;
  15. };
  16. class Date
  17. {
  18. public:
  19.     Date(int year = 2025, int month = 1, int day = 1)
  20.         :_year(year)
  21.         , _month(month)
  22.         , _day(day)
  23.     {}
  24.     void SetTimeOfDate(int hour, int minute, int second)
  25.     {
  26.         // 直接访问时间类私有的成员变量
  27.         _t._hour = hour;
  28.         _t._minute = minute;
  29.         _t._second = second;
  30.     }
  31. private:
  32.     int _year;
  33.     int _month;
  34.     int _day;
  35.     Time _t;
  36. };
复制代码
4. 内部类

一个类界说在另一个类的内部,这个内部的类就叫内部类。
它不属于外部类,不能通过外部类的对象去访问内部类的成员(外部类对内部类没有任何超越的访问权限),但内部类是外部类的友元类,内部类可以通过外部类对象参数访问外部类中所有成员。
留意事项:
1. 内部类可以界说在外部类的任意地方(犹如友元)
2. 内部类可以直接访问外部类的static成员,不需要外部类的对象/类名
3. sizeof(外部类)= 外部类,相当于内部类不存储在外部类
  1. class A
  2. {
  3. private:
  4.         static int a;
  5.         int b;
  6. public:
  7.         // B是A的友元
  8.         class B
  9.         {
  10.         public:
  11.                 void fun(const A& i)
  12.                 {
  13.                         //不用外部类的对象
  14.                         cout << a << endl;
  15.                         cout << i.b << endl;
  16.                 }
  17.         };
  18. };
  19. int A::a = 1;
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊落一身雪

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表