<C++> 类(2):对象的种类 类之间的关系

一.对象的种类

1.全局对象:

①生命周期:程序结束

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

2.栈区局部对象:

①生命周期:作用域结束

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

3.堆区的指针对象:

①生命周期:遇到delete结束

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

4.临时对象:

扫描二维码关注公众号,回复: 1549386 查看本文章

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

②代码说明:

 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.总结:

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

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

猜你喜欢

转载自www.cnblogs.com/Aaaaaalei0612/p/9156657.html
今日推荐