【C++】类与对象篇四

[复制链接]
发表于 2026-2-1 05:30:23 | 显示全部楼层 |阅读模式
一 . 再谈构造函数

1 . 构造函数体赋值

在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个符合初始值
  1. class Date
  2. {
  3. public:
  4. Date(int year, int month, int day)
  5. {
  6. _year = year;
  7. _month = month;
  8. _day = day;
  9. }
  10. private:
  11. int _year;
  12. int _month;
  13. int _day;
  14. };
复制代码
固然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化由于初始化只能初始化一次,而构造函数体内可以多次赋值
2. 初始化列表

初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"背面跟一个放在括号中的初始值或表达式
  1. class Date
  2. {
  3. public:
  4. Date(int year, int month, int day)
  5. : _year(year)
  6. , _month(month)
  7. , _day(day)
  8. {}
  9. private:
  10. int _year;
  11. int _month;
  12. int _day;
  13. };
复制代码
  【留意】
  

  • 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
  • 类中包罗以下成员,必须放在初始化列表位置举行初始化:引用成员变量,const成员变量,自界说范例成员(且该类没有默认构造函数时)
  • 只管使用初始化列表初始化,由于不管你是否使用初始化列表,对于自界说范例成员变量,肯定会先使用初始化列表初始化。
  • 成员变量在 类中声明序次就是其在初始化列表中的初始化序次 ,与其在初始化列表中的先后序次无关
  1. class A
  2. {
  3. public:
  4. A(int a)
  5. :_a1(a)
  6. ,_a2(_a1)//先执行这里,此时_a1为随机值
  7. {}
  8. void Print() {
  9. cout<<_a1<<" "<<_a2<<endl;
  10. }
  11. private:
  12. int _a2;
  13. int _a1;
  14. };
  15. int main() {
  16. A aa(1);
  17. aa.Print();
  18. }
复制代码
运行结果:

3. explicit关键字

构造函数不光可以构造与初始化对象,对于吸取单个参数的构造函数,还具有范例转换的作用。吸取单个参数的构造函数详细表现:

  • 构造函数只有一个参数
  • 构造函数有多个参数,除第一个参数没有默认值外,别的参数都有默认值
  • 全缺省构造函数
    总结:用explicit修饰构造函数,将会克制构造函数的隐式转换。


二 . static成员 【口试题】

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。静态成员变量肯定要在类外举行初始化
静态成员函数特殊的特殊调用方式类名 + :: + 函数名由于它没有this指针,无法通过该类的对象调用
[ 口试题 ]:实现一个类,盘算步调中创建出了多少个类对象。
  1. class A
  2. {
  3. public:
  4.         A() { ++_scount; }
  5.         A(const A& t) { ++_scount; }
  6.         ~A() { --_scount; }
  7.         static int GetACount() { return _scount; }
  8. private:
  9.         static int _scount;
  10. };
  11. int A::_scount = 0;
  12. int main()
  13. {
  14.         cout << A::GetACount() << endl;
  15.         A a1, a2;
  16.         A a3(a1);
  17.         cout << A::GetACount() << endl;
  18.         return 0;
  19. }
复制代码

2.2 特性
   

  • 静态成员为全部类对象所共享,不属于某个详细的对象,存放在静态区
  • 静态成员变量必须在类外界说,界说时不添加static关键字,类中只是声明
  • 类静态成员即可用 类名::静态成员 大概 对象.静态成员 来访问
  • 静态成员函数没有隐蔽的this指针,不能访问任何非静态成员
  • 静态成员也是类的成员,受public、protected、private 访问限定符的限定
  【标题】

  • 静态成员函数可以调用非静态成员函数吗?
  • 非静态成员函数可以调用类的静态成员函数吗?
三 . 友元

友元提供了一种突破封装的方式,偶然提供了便利。但是粉碎了封装,以是友元不宜多用。
友元分为:友元函数和友元类
1. 友元函数

标题:如今实行去重载operator<<,然后发现没办法将operator<<重载成成员函数。由于cout的输出流对象和隐含的this指针在抢占第一个参数的位置this指针默认是第一个参数也就是左使用数了。但是实际使用中cout必要是第一个形参对象,才气正常使用以是要将operator<<重载玉成局函数。但又会导致类外没办
法访问成员,此时就必要友元来办理
。operator>>同理。
  1. class Date
  2. {
  3. public:
  4. Date(int year, int month, int day)
  5. : _year(year)
  6. , _month(month)
  7. , _day(day)
  8. {}
  9. // d1 << cout; -> d1.operator<<(&d1, cout); 不符合常规调用
  10. // 因为成员函数第一个参数一定是隐藏的this,所以d1必须放在<<的左侧
  11. ostream& operator<<(ostream& _cout)
  12. {
  13. _cout << _year << "-" << _month << "-" << _day << endl;
  14. return _cout;
  15. }
  16. private:
  17. int _year;
  18. int _month;
  19. int _day;
  20. };
复制代码
友元函数可以直接访问类的私有成员,它是界说在类外部的平常函数,不属于任何类,但必要在类的内部声明,声明时必要加friend关键字
  1. class Date
  2. {
  3. friend ostream& operator<<(ostream& _cout, const Date& d);
  4. friend istream& operator>>(istream& _cin, Date& d);
  5. public:
  6. Date(int year = 1900, int month = 1, int day = 1)
  7. : _year(year)
  8. , _month(month)
  9. , _day(day)
  10. {}
  11. private:
  12. int _year;
  13. int _month;
  14. int _day;
  15. };
  16. ostream& operator<<(ostream& _cout, const Date& d)
  17. {
  18. _cout << d._year << "-" << d._month << "-" << d._day;
  19. return _cout;
  20. }
  21. istream& operator>>(istream& _cin, Date& d)
  22. {
  23. _cin >> d._year;
  24. _cin >> d._month;
  25. _cin >> d._day;
  26. return _cin;
  27. }
  28. int main()
  29. {
  30. Date d;
  31. cin >> d;
  32. cout << d << endl;
  33. return 0;
  34. }
复制代码
  1 .友元函数可访问类的私有和掩护成员,但不是类的成员函数
2 . 友元函数不能用const修饰
3 . 友元函数可以在类界说的任何地方声明,不受类访问限定符限定
4 . 一个函数可以是多个类的友元函数
5 . 友元函数的调用与平常函数的调用原理类似
  2. 友元类

友元类的全部成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
1 . 友元关系是单向的,不具有交换性。
好比Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不可。
2 . 友元关系不能通报
假如B是A的友元,C是B的友元,则不能阐明C是A的友元。
3 . 友元关系不能继承
  1. class Time
  2. {
  3. friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成
  4. 员变量
  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 = 1900, 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. };
复制代码
四 . 内部类

假如一个类界说在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何良好的访问权限
留意:内部类就是外部类的友元类,拜见友元类的界说,内部类可以通过外部类的对象参数来访问外部类中的全部成员。但是外部类不是内部类的友元
特性:
   

  • 内部类可以界说在外部类的public、protected、private都是可以的,而且受访问限定符的束缚。
  • 留意内部类可以直接访问外部类中的static成员,不必要外部类的对象/类名。
  • sizeof(外部类)=外部类,和内部类没有任何关系。
  1. class A
  2. {
  3. private:
  4.         static int k;
  5.         int h = 3;
  6. public:
  7.         class B // B天生就是A的友元
  8.         {
  9.         public:
  10.                 void foo(const A& a)
  11.                 {
  12.                         cout << k << endl;//OK
  13.                         cout << a.h << endl;//OK
  14.                 }
  15.         };
  16. };
  17. int A::k = 1;
  18. int main()
  19. {
  20.         A::B b;
  21.         b.foo(A());
  22.         return 0;
  23. }
复制代码
运行结果:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表