<C++> 类(2):对象的种类 类之间的关系 重载操作符operator

一.对象的种类

1.全局对象:

①生命周期:程序结束

②执行顺序:return 0 → } → 析构

2.栈区局部对象:

①生命周期:作用域结束

②执行顺序:return 0 → 析构 → }

3.堆区的指针对象:

①生命周期:遇到delete结束

注:new出来的对象没有delete就没有析构函数 哪怕是作用域结束了也没有

4.临时对象:

①生命周期:仅限当前这一行

②代码说明:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 class CPerson
 5 {
 6 public:
 7     CPerson QQ()
 8     {
 9         CPerson qq;
10         return qq;
11     }
12 };
13 
14 int main()
15 {
16     CPerson kk;
17     kk = kk.QQ();
18 
19     return 0;
20 }

其实到return pp的那一行 return完了就已经把qq删了 所以才会创建一个临时对象接着qq的值

也就是说 下面主函数在第17行执行调用QQ函数的时候 会在这一行创建一个临时对象

临时对象的产生是电脑做的 临时对象的构造函数执行的是电脑里面默认的

用这个临时对象接着函数的返回值 然后把这个临时对象装在kk里面

如果你不想让他创建临时对象的话 可以把函数返回值和参数改成CPerson&类型的

返回值类型如果是CPerson 那么在外面就叫创建临时对象

返回值类型如果是CPerson& 这就相当于只是把一个名字拿出来了

总结:大部分对象都是在堆区new出来的 因为这样比较方便去控制他的生命周期

5.为什么有了malloc和free还要有new和delete呢?(new还是用malloc去定义的)

malloc和free是不调用构造函数和析构函数的 只是单纯的去申请空间和释放空间的

但是!!!

new:①分配空间 ②调用构造和初始化 ③返回空间地址

delete:①调用析构 ②删除对象空间

也就是说:new和delete都可以触发构造函数和析构函数

6.杂乱补充:

空类的大小:一个字节(后面还会对空类的内容进行补充)

类是抽象的 不存在的 是有定义类的实体 也就是只有定义对象的时候 才会被分配空间

②成员变量和成员函数:

成员变量是在创建对象的时候就存在的 普通的成员变量每个对象都有一份 静态成员变量是所有对象公用一份(这个在后面也会再写 具体有所补充)

成员函数是在编译的时候就存在了 并且只有一份

③不同的地址取得的就是不同的变量 谁调用就用谁的地址 就把谁的地址传进去

普通的成员函数 都会有一个隐藏的参数:CPerson* this(拿CPerson为例)

每一个普通的成员参数都有一个隐藏的指针this 这个指针用来装调用对象的地址 用来区分不同对象的成员

例如:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 class CPerson
 5 {
 6 public:
 7     int a;
 8 public:
 9     CPerson(int b)
10     {
11         a = b;
12     }
13     void Show(/*CPerson* this*/)
14     {
15         cout << this << endl;
16         cout << this -> a << endl;
17     }
18 };
19 
20 int main()
21 {
22     CPerson aa(100);
23     cout << &aa << endl;
24     aa.Show(/* &aa */);
25 
26     CPerson bb(200);
27     cout << &bb << endl;
28     bb.Show(/* &bb */);
29     return 0;
30 }

二.类之间的关系

类之间的关系分为两种:

1.纵向关系:继承

①语法:class CSuperman : public CPerson{ ... };

把父类中的所有成员拿过来

横线处的访问修饰符可以替换 访问修饰符不同 继承过来也是有差别的

 1 #include<iostream>
 2 using namespace std;
 3 
 4 class CPerson
 5 {
 6 public:
 7     void ShowEat()
 8     {
 9         cout << "吃饭" << endl;
10     }
11 };
12 
13 class CSuperMan : public CPerson
14 {
15 public:
16     void ShowFly()
17     {
18         cout << "我能飞" << endl;
19     }
20 };
21 
22 int main()
23 {
24     CSuperMan sm;
25     sm.ShowEat();
26     sm.ShowFly();
27 
28     return 0;
29 }

②原有类:基类 父类

新类:派生类 子类

③作用:提高复用性

④父类和子类中同名的成员变量和成员函数是通过作用域来区分的

子类的大小=子类+父类

 1 #include<iostream>
 2 using namespace std;
 3 
 4 class CFather
 5 {
 6 public:
 7     int m_nMoney;
 8 public:
 9     CFather()
10     {
11         m_nMoney = 1000000;
12     }
13 };
14 
15 class CSon : public CFather
16 {
17 public:
18     int m_nMoney;
19 public:
20     CSon()
21     {
22         m_nMoney = 100;
23     }
24 };
25 
26 int main()
27 {
28     CFather cf;
29     CSon cs;
30 
31     cout << cs.m_nMoney << endl;
32     cout << cs.CFather::m_nMoney << endl;
33     cout << sizeof(cs) << endl; //输出 8
34 
35     return 0;
36 }

继承方式:影响的是继承过来的访问修饰符 即子类的访问修饰符

public继承:public和protected没有变化 但是父类的private在子类中是不可访问的

protected继承:public变成protected protected不变 private依然不可访问

private继承:public和protected都变成private 所有内容不可访问

特别注意:自己的类中不可定义自己的类对象 但是定义指针可以!!!

⑦继承关系的构造和析构函数的调用顺序:

定义一个派生类对象:先执行父类构造 然后子类构造 然后子类析构 父类析构

换句话说 构造函数是从父类到子类 析构是从子类到父类

 1 #include<iostream>
 2 using namespace std;
 3 
 4 class CFather
 5 {
 6 public:
 7     CFather()
 8     {
 9         cout << "CFather" << endl; 
10     }
11     ~CFather()
12     {
13         cout << "~CFather" << endl; 
14     }
15 };
16 
17 class CSon : public CFather
18 {
19 public:
20     CSon()
21     {
22         cout << "CSon" << endl; 
23     }
24     ~CSon()
25     {
26         cout << "~CSon" << endl; 
27     }
28 };
29 
30 int main()
31 {
32     CSon son;
33 
34     return 0;
35 }

注意:

父类的构造函数是在子类的构造函数初始化列表中调用的 默认的调用是无参的

如果父类中只有带参数 也需要在子类的构造函数初始化列表中调用带参数的

2.横向关系:依赖<关联<聚合<组合

①组合:是部分与整体的关系

它是你的一部分 缺少一部分就是不完整的

直接要求:包含对象对被包含对象的拥有 以及 包含对象与被包含对象生命期的关系

例如:笔记本电脑和笔记本电脑键盘 汽车和轮胎 人和手

②聚合:是一对多的关系

暗含了一种所属关系以及生命期的关系(有无是不一定的) 被聚合对象还可以再被别的对象关联

注意:是A中放了多个B 而不是A中放了B C D

例如:班级有很多人 部门有很多职工

③关联:

某个对象长期持有对另一对象的引用 可以随时解除关联或者进行关联

关联是没有生命周期的 可以是相互的

例如:朋友(人在出生的时候 可以在类里放一根指针 有就指向这个对象 没有就指空)

④依赖:

某个对象的功能依赖另外一个对象 被依赖的对象只作为工具使用

依赖是没有生命周期的 只是使用 不持有对它的引用

例如:人依赖空气呼吸

3.总结

①有生命周期的:组合和聚合

②没有生命周期的:关联和依赖

三.重载操作符operator

1.重载操作符有两种方法:

在类内:调用的对象一定在左边

在类外:需要有符号左边和符号右边(双目运算符)

2.需要注意的地方:

①表达式都有结果 所以重载的符号需要有返回值 返回值是为了和其他符号结合

②在重载输入输出操作符的时候 输入一定要放& 否则是改变不了其中的内容的

输出无所谓(这么说未免太不负责任) 但是为了养成良好的习惯 还是都加上比较好 也方便记忆嘛

3.代码:

 1 #include<iostream>
 2 using namespace std; 
 3 
 4 class CNum
 5 {
 6 public:
 7     int m_num; 
 8 public:
 9     CNum(void)
10     {
11     }
12 
13     ~CNum(void)
14     {
15     }
16 
17     int operator=(int num)
18     {    
19         this -> m_num = num;
20         return m_num;
21     }
22 
23     int operator+(int num)
24     {
25         return this -> m_num + num;
26     }
27 
28     int operator++()
29     {
30         m_num = m_num + 1;
31         return m_num;
32     }
33 
34     int operator++(int aaa)
35     {
36         aaa = m_num;
37         m_num = m_num + 1;
38         return aaa;
39     }
40 };
41 
42 int operator+(int num,CNum& cn)
43 {
44     return num + cn.m_num;
45 }
46 int operator+(CNum& cn1,CNum& cn2)
47 {
48     return cn1.m_num + cn2.m_num;
49 }
50 
51 istream& operator>>(istream& is,CNum& cn)
52 {
53     cin >> cn.m_num;
54     return is;
55 }
56 
57 ostream& operator<<(ostream& os,CNum& cn)
58 {
59     cout << cn.m_num;
60     return os;
61 }
62 
63 int main()
64 {
65     CNum a;
66     a = 100;
67     cout << a.m_num << endl; //100
68 
69     CNum b;
70     b = a = 200;
71     cout << a.m_num << endl; //200
72     cout << b.m_num << endl; //200
73 
74     CNum c;
75     c = a + 100;
76     cout << c.m_num << endl; //200+100=300
77 
78     CNum d;
79     d = 100 + a;
80     cout << d.m_num << endl; //100+200=300
81 
82     CNum e;
83     e = a + b;
84     cout << e.m_num << endl; //200+200=400
85 
86     cin >> a;
87     cout << a << endl;
88 
89     return 0;
90 }

 

转载于:https://www.cnblogs.com/Aaaaaalei0612/p/9156657.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值