300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 173-C++面向对象高级开发-上(侯捷)

173-C++面向对象高级开发-上(侯捷)

时间:2022-12-23 10:37:15

相关推荐

173-C++面向对象高级开发-上(侯捷)

1、c++编程简介

类中带有指针和类中不带有指针

2、头文件与类的声明

c++将数据和函数包在一起。

经典的class分类,带指针和不带指针的,具有代表性的就是我们写的两个案例: 复数案例和字符案例复数案例: 数据有很多份,函数只有一份(复数的加减乘除…)字符案例: 里面只有一个指针,数据用指针指出去,这是这两点的不同ppt中的字符串的大小,每个里面只有一个指针

标准库用的是<>,自己的头文件用的是“”

防卫式声明:

写的任何一个头文件,最好都加一个防卫式声明。

模板表现形式:现在是什么类型还没有决定;

类模板需要提供类的类型。

3、构造函数

inline:内联函数函数在类中定义完成,就叫做inline;简单来说,若果程序太复杂,就没有办法inline;(能不能编程inline,由编译器自己决定)

函数在本体中就像成了一个inline,函数是inline会很快 外面的函数我们可以自己加上inline,能不能成inline由编译器自己决定。

所有的数据都应该是private;外界需要调用的函数,用public;处理自己数据的函数可以用private;

构造函数:函数名和类名相同不需要有返回值

**构造函数的赋值:**要培养好的,大气的写法

不要这样写:

用c++构造函数的特殊写法—初始化列表(构造函数独有的):

总结:一个变量的值的设定:有两个阶段,初始化(在大括号之前,效率比较高)和赋值(在大括号中)。

不带指针的类(系统会自己提供析构函数),多半不用写析构函数

**函数重载发生的条件:**参数值,类型;返回值不能作为重载的条件

构造函数1和2,2是对1进行的重载,此时如果在右边进行创建对象时,

编译器也不知道该调用哪个。

4、参数传递和返回值

构造函数写在private中(表示不可以被外界调用的):

设计模式:单例模式Singleton

在小括号的后面加上 const(位置:小括号后面,花括号前面):只读不写

const complex c1(2,1):变量或者对象的内容是不可以改变的注意:函数处的const和创建对象时的const都需要加const

参数传递最好用引用进行传递,引用传递不希望将自身进行改变,在引用的前面加上const。

基本标准:1. 数据在private2. 参数传递尽可能用引用进行传入3. 函数返回值尽可能用引用4. 函数和对象该加const处要加const5. 构造函数使用初始化参数列表

相同的class可以互相调用参数和成员函数。

什么情况下不能return by reference

5、操作符重载与临时对象

c++允许对操作符进行重载:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bqm34rI0-165709606)(…/…/assets/c++面向对象高级开发-上/image-0222105148361.png)]

任何一个成员函数,都会隐藏一个this指针(虽然没有写,但是它是在的),谁调用函数就是this,this就指向谁;写代码时,this是不能写,写出来就错了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jpUX3017-165709606)(…/…/assets/c++面向对象高级开发-上/image-0222105539073.png)]

传递者无需知道接受者是以“引用”的方式进行传递。

下面的引用返回值:可以满足操作者的连续操作c3+=c2+=c1。

全局函数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IFVCh2Kc-165709607)(…/…/assets/c++面向对象高级开发-上/image-0222105624702.png)]

**注意:**全局函数没有this指针;

这里函数返回值没有用引用进行接收,因为,return返回的是临时对象

因为这里函数中会创建一个新的对象,来接收相加的值,如果用引用,函数调用结束后,本体会消失,引用出错,因此用complex作为返回值。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RJOXfKHZ-165709607)(…/…/assets/c++面向对象高级开发-上/image-0222110515605.png)]

临时对象,函数结束就会消失,不用怕,因为会返回出去。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r59K55jE-165709607)(…/…/assets/c++面向对象高级开发-上/image-0222110534411.png)]

complex();-- 临时对象,没有参数,就是默认值0;complex(4,5); -- 也是临时对象;这两个临时对象,进行到下一行,这两个对象均没有了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XgE2FD8K-165709608)(…/…/assets/c++面向对象高级开发-上/image-0222110646935.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dHSQhgO2-165709608)(…/…/assets/c++面向对象高级开发-上/image-0222110725219.png)]

**注意:**这里是可以用引用的(并没有产生一个loacl对象),这样不是最好的。

等号“=="的重载:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pBTk3IRV-165709609)(…/…/assets/c++面向对象高级开发-上/image-0222111041132.png)]

不等号“!=”的重载:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TAqjMZJG-165709609)(…/…/assets/c++面向对象高级开发-上/image-0222111220477.png)]

共轭复数:实部相等,虚部相反数

注意:任何一种实现都可以将其写成全局函数成员函数,都可以解决问题;

重载“<<”:

”<<“ 不可能认识一个新的类型,将其输出到屏幕上进行重载(重载它只能使用全局的方式)。

cout的类型是ostream,ostream前面不能加const,实际上在往函数中的os每丢任何东西都在改变os的状态。之后再return后面想怎么输出就怎么输出了。

**同样:**返回值可以用void,想远一点,使用者可能想连串使用<<,因此应ostream&,返回引用进行输出。ostream&前面不能加const,因为在连串使用时,状态会发生改变。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OHDAQM03-165709610)(…/…/assets/c++面向对象高级开发-上/image-0222111627082.png)]

c++是自由形式,加几个空格都无所谓。

总结:设计一个class需要注意的事情:1. 构造函数的初始化;2. 函数该不该加const一定要考虑;3. 参数的传递尽量考虑“引用传递(pass by reference)”,以及前面要不要加const;4. 返回值尽量考虑“引用传递(pass by reference)”,以及前面要不要加const;5. 数据放在private,函数大部分放在public;

6、复习complex类的实现过程

编程的好习惯:

1、 防卫式的常数定义

2、数据私有化private,数据的类型double

3、class的构造函数,构造函数初始化列表 {}:可用于其他文件开辟内存,生成文件等。

4、重载+=符号,对类进行加法,重载函数有两种形式

成员函数全局参数

成员函数的好处:

返回值可以用引用,调用时可以使用成员函数独有的this指针,因此重载函数只需一个参数,默认的this指针 ,谁调用就是谁。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HdVjHYCO-165709610)(…/…/assets/c++面向对象高级开发-上/image-0222112611683.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jfXMaHFt-165709611)(…/…/assets/c++面向对象高级开发-上/image-0222112639099.png)]

**全局函数:**返回值不能用引用,需要传入两个参数。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xjn9Tkxj-165709611)(…/…/assets/c++面向对象高级开发-上/image-0222114114354.png)]

5、函数后面加上const;

如果函数后面并没有改动private中的数据,就需要在()加上const。

6、友元:可以访问class中的私有成员

7、inline函数

​ 可以在类内,也可以在类外定义。

8、类内声明的函数,在类外实现

加上complex::类作用域;类内的成员函数自带this指针,谁调用就是谁;只需传+=右边的参数,用引用方式传入;该参数无需改变,在前面加上const;返回值可以用引用,因为是+=,将值给已经存在的对象;将接受到的参数给另一个参数去做;return _doapl (this,r);inline函数,你自己加,到底编译器加不加,看编译器。

这里是可以传引用的,因为左边本来是有一个的this指针的(不是局部变量);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EMPIkc7A-165709612)(…/…/assets/c++面向对象高级开发-上/image-0222120004449.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uA6wPD3G-165709612)(…/…/assets/c++面向对象高级开发-上/image-0222120011112.png)]

9、全局函数

加法操作,为什么用全局函数,不用成员函数?加法包括:复数+实数,实数+复数,复数+复数,比较复杂,如果用成员函数,只能复数和复数相加,因此用全局函数 ;

类名+():表示临时对象,代码执行到下一行就会被释放;

这里它用了返回值进行返回,这样就可以对它的值进行返回

返回值用的complex,不能用引用(这里return的是一个临时变量)

10、“<<”操作符重载(写成非成员函数)

操作符重载一定是作用在左边的操作数上;传入的x可以使用引用方式,并且前面加上const;ostream(是一个类)前面不可以加const,因为os的状态是一直发生变化的;<<使用者如果想连串的使用,返回值设置为引用的类型ostream&;

7、三大构造函数:拷贝构造、拷贝赋值、析构

**另外一个经典的例子:**class中有指针 ,用字符串string来进行设计

拷贝构造和**拷贝赋值:**前面的complex例子,如果类中没有写,编译器起始内部给你写好了,复数比较简单,类中没有指针,不需要写,用编译器给的就足够了。

class中带指针,一定要自己写 拷贝构造 和 拷贝赋值。

拷贝构造和拷贝赋值:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oEO1KdgE-165709612)(…/…/assets/c++面向对象高级开发-上/image-0222170636278.png)]

String s3(s1); //拷贝构造s3 = s2; //拷贝赋值

字符串设计成指针类型,可以进行动态的开辟空间;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QfgvaxR8-165709613)(…/…/assets/c++面向对象高级开发-上/image-0222170721638.png)]

构造函数:String(const char*cstr)=0;拷贝构造函数:String(const String& str);拷贝赋值函数:String& operator=(const String& str);析构函数:~String();

7.1、构造函数

String(const char* cstr)=0;

传入一个指针,判断其是否为空,如果不是空,采用strlen确定字符创的大小+1(最后还是有一个结束符号’\0’的,需要+1);用完之后,需要在析构函数中,delete对内存进行释放,否则会造成内存泄漏;使用strcpy进行赋值字符串。

构造函数中传入一个指针:为什么传入一个指针?

从c语言延续的概念,

字符串:一个指针指着头,后面有一串,最后面有个"\0"这样的结束符号。

字符串的大小:(怎么设计?)

不知道有多长,后面有个结束符号,可以知道有多长;后面没有结束符号,前面有长度这个整数。

7.2、析构函数

将开辟的内存空间进行释放,否则就是内存泄漏了;

调用3次析构函数。

7.3、拷贝构造函数

类中数据有指针,就必须有拷贝构造和拷贝赋值

​ 如果使用浅拷贝操作带有指针的class,因为ab中都是指针,都会指出去,从而得到数据如果对其进行浅拷贝,会使得两个指针指向同一块数据,原来的数据会单独存在,造成内存泄漏,两个指针指向同一块区域,在进行内存释放时,会重复释放,出错!

上面使用的是默认的拷贝构造和拷贝赋值;

深拷贝:

7.4、拷贝赋值函数

注意:成员函数是有this指针的。

delete[] m_data,首先将新空间进行清空;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VJNyx2w1-165709613)(…/…/assets/c++面向对象高级开发-上/image-0222173215423.png)]

m_data=new char[strlen(str.m_data)+1],重新将新空间进行开辟,和传进来的空间一样大; **strcpy(m_data,str.m_data),**将传入的字符串赋值给新的字符串

注意:一定要检查是否进行了自我赋值,检查是不是出现了s3=s3这种情况(不用进行后续部分,效率高)

if(this == &str)//检测自我赋值 &str表示取地址return*this注意&符号的使用:出现在typename后面:string& str 表示引用;出现在对象前面:&str 表示取地址。

​ 如果两个对象是相同的,进行了拷贝赋值操作,开始时,两个相同的对象指向同一块内存,如果将其删除之后,这是后就会出错,他需要靠另一个对象的长度,此时找不到另一个,报错!

7.5、ostream

class中定义的 get_c_str() 成员函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JHYcuIm4-165709614)(…/…/assets/c++面向对象高级开发-上/image-0222173701958.png)]

这里重载了"<<"符号。

8、堆、栈与内存管理

8.1、栈和堆

**栈:**存在于某个作用域的一块内存空间;(函数{}里面就是一个作用域)

Complex c1(1,2):开辟在栈区,程序指向结束后,会自动调用析构函数,将其释放.Complex* p=new Complex(3):在堆区开辟一块内存,将创建的对象放入,堆区空间由程序员手动开辟,手动释放,不会自动释放。

8.2、栈对象的生命期

c1存放在栈区,函数的作用域结束(就是离开大括号之后就没有了)之后结束,自动释放,调用析构函数。

8.3、静态对象

生命在作用域结束后仍然存在,直至整个程序结束

析构函数在整个程序结束时调用。

8.4、全局对象

析构函数在整个程序结束时调用。

8.5、堆中创建对象

右图:没有释放自己开辟的内存,会造成内存泄漏

**注意:**指针在离开右边大大括号之后,指针会死亡,但是开辟的空间还是存在的,对该内存失去了控制,内存泄漏。

8.5.1、new操作

三个步骤:

分配内存,是void*类型将void型的指针转换为Complex型的指针最后调用构造函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5gvkgdFI-165709614)(…/…/assets/c++面向对象高级开发-上/image-0224115604181.png)]

new:先分配内存,再调用构造函数。

operator new是一个函数,这个函数的内部是malloc函数,相当于调用malloc函数;

8.5.2、delete操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f6X4q0Pa-165709615)(…/…/assets/c++面向对象高级开发-上/image-0224115754901.png)]

delete操作:先调用构造函数,再释放内存。

调用析构函数,**将字符串里面动态分配的内容给杀掉,**字符串本身只是一个指针而已;

c++调用operator delete ,源代码内部调用的是free(ps),将字符串本身(指针)给杀掉

8.6、动态分配所得的内存块(memory block)in VC

8.6.1、Complex类分配内存—类中无指针

**每一小格子:**4bit

调试模式下:(左1)

​ 创建一个Complex对象:本身:绿色8bit + 灰色:上面8个+下面1个(8*4+4=32bit)+上下2个橘色的cookie(2*4=8)=52。

​ 由于vc创建的大小必须是16的倍数,因此需要将52填补成64(用图中pad进行填补,蓝色的)

问题:内存这么大,产生浪费?

浪费是必要的浪费,以后进行回收时,方便回收。

学生一般不会进入调试模式(下图为非调试模式(没有灰色的)16个bit,正好),16的倍数。

非调试模式:(左2)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-03nrBfQY-165709615)(…/…/assets/c++面向对象高级开发-上/image-0224120314642.png)]

**上下cookie的作用:**最主要的是记录整块给你的大小,因为在释放时,只会给你一个指针,知道总大小,才方便释放。

00000041:

​ 采用的是16进制,4表示:4*16^1=64,最后一位的表示内存状态(1表示内存给出去了,0表示还给操作系统)

8.6.2、string类—类中有指针

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8P8dEUit-165709615)(…/…/assets/c++面向对象高级开发-上/image-0224120542857.png)]

对于string类,字符串本身内含一个指针,大小为4。

调试模式下:(左3)

​ **分配内存大小:**本身4+加上灰色的(上面32+下面4)+上下cookie(4*2) = 48

00000031:采用的是16进制,3表示:3*16^1=64,最后一位的表示内存状态(1表示内存给出去了,0表示还给操作系统)

非调试模式下:(左4)

分配内存大小:本身4+上下cookie(4*2)+pad填补的4=16,正好是16的倍数;

8.6.2、array动态分配

如果开辟的是数组char[],则在释放空间时,需要delete []…,使用中括号

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SXygnwt7-165709616)(…/…/assets/c++面向对象高级开发-上/image-0224121207648.png)]

内存分析:

**左1:**3个复数(3x8,灰色部分)+调试模式(32+4,黄色部分)+上下2个cookie(4x2)+4(左1中的3:用来记录有3个复数)=52,将其扩展为16的倍数:80(利用蓝色的pad进行扩充)。

**内存大小为80:**采用的是16进制,3表示:5*16^1=80,最后一位的“1”表示内存状态(1表示内存给出去了,0表示还给操作系统)。

**左2:**非调试模式下;

**左3:**string调试模式;

**左4:**string非调试模式;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fbCxn6XJ-165709616)(…/…/assets/c++面向对象高级开发-上/image-0224142907824.png)]

**使用了[]之后,**系统知道是要删除的是数组(没有写[],编译器会理解成只有1个,只会调用1次[]),因此会调用3此析构函数,将其各个元素动态开辟的空间删除。

**注意:**字符串占用的空间释放了,是字符串的元素在堆区开辟的空间没有一一释放。

9、复习String类的实现过程

防卫式定义

设计字符串时,由于其大小不好指定,因此里面放指针

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fHBosGjX-165709616)(…/…/assets/c++面向对象高级开发-上/image-0224143145029.png)]

构造函数、拷贝构造、拷贝赋值、析构函数、访问字符串函数get_c_str()的声明;

在类外写构造函数和析构函数;

使用strlen和strcpy时需要包含头文件:#include <string.h>

array new一定要搭配array delete,需要带中括号。

记得不管怎样,都要在类外函数中加—inline(不管编译器能不能帮你做成inline函数)

拷贝构造函数拷贝赋值函数

希望进行连串的操作,因此返回值类型用string&;

成员函数是自带this指针的;

拷贝赋值一定要注意是不是自我赋值

10、类模板

10.1、static函数补充

成员函数会有一个隐藏的this指针;

非静态成员:

通过this指针调用c1、c2、c3;c1.real()和complex::real(&c1)等价的。

静态成员(静态变量、静态成员函数):

加了static成为静态变量之后,就和对象脱离了;不属于对象,在内存的某个区域,单独的存在一份;这种静态的数据只有一份。

**静态变量使用情况:**比如去银行开户,100万人,他们的利率都是一样的,因此需要经利率设置为静态变量。

**静态函数使用情况:**没有this指针,不能像一般的成员函数去访问、处理对象;静态函数,如果要处理数据,只能处理静态数据。

静态变量的声明和定义:

在类内对静态变量进行声明:

static double m_rate;

类外对静态变量进行定义:

double Account::m_rate=8.0;

静态函数的调用:

通过对象调用;通过类型调用;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cwdy39PE-165709617)(…/…/assets/c++面向对象高级开发-上/image-0224145222118.png)]

10.2、单例设计模式

**单例设计模式:**将构造函数放在private中;

在private中放一个static A a自己,已经创建了一个a;

不想让外界创建A(将构造函数放在private中),这样A就只有一份a;

**缺点:**如果外界都没有用到,a就是一种浪费。

更好的写法:

将只有一份的A放到成员函数中,因为构造函数是私有化,因此只有一份;而且,只有调用getInstance成员函数时,才会创建 a。

10.3、cout的补充**(为什么cout可以接受各式各样的数据?)**

对里面很多的操作符进行了重载,能接受很多操作符;cout是一种ostream,继承的ostream

10.4、类模板

在调用时,必须使用**<>**指出传入的类型:complexc2(2,6)

需要指定模板的类型<数据类型>;

complex<int>c2(2,6)

10.5、函数模板

运算符重载:在stone类内重载了小于号

10.6、namespace 补充

在这之前谈的就是对单一的class怎么写的 ,接下来就是面向对象编程,类和类之间的关系。

11、组合与继承

11.1、Composition—复合

复合(Composition):一个类中有另外一个类;

queue:队列,底层是deque

deque:双端数组

queue内含一个deque;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D5DU2iRz-165709617)(…/…/assets/c++面向对象高级开发-上/image-0224151518462.png)]

黑色菱形表示,它里面有其他东西;(本例中,queue中有deque)

queue类中包含deque类型,可以调用deque中的函数,Adapter设计模式。

**注意:**这里queue里面的函数大多数都是直接使用的是deque容器里面的;

11.1.1、复合的内存分析

**黑色菱形+箭头:**表示一个里面包含另一个;

Container里面包含Component,黑色菱形表示一个里面包含另一个;

11.1.2、复合类型构造和析构时机

**构造时:**先构造内部,再构造外部;**析构时:**先析构外部,再析构内部。

都是编译器帮我们安排好的。

11.2、Delegation/Composition by reference—委托

一个类中包含另一个类的指针。

**两个类的生命是不同步的,**需要调用指针时,才创建;

前面的复合(Compositon),两者生命是相同的。

**空心的菱形表示指针:**String里面包含StringRep的指针

11.3、Inheritance—继承

**空心三角+直线:**表示继承关系;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F345qyfJ-165709618)(…/…/assets/c++面向对象高级开发-上/image-0224153102946.png)]

**右上角的"T":**表示的是模板的意思;

继承:父类数据会被完整的继承下来。

11.3.1、继承的构造和析构函数之间的关系

子类继承父类,子类的数据范围 > 父类

**构造函数:**先构造父类,再构造子类;**析构函数:**先析构子类,再析构父类。

父类的析构函数必须是虚函数;

只要类会变成一个父类,或者将来会变成一个父类,就将它的析构函数设置为虚函数。

12、虚函数与多态

12.1、虚函数—virtual function

**非虚函数:(**没有加virtual的一般成员函数)不希望子类重新定义父类函数;虚函数:(在成员函数前面加上virtual,成为虚函数)父类中已经有默认定义,希望子类重新定义它;纯虚函数:子类一定要重新定义纯虚函数(父类中没有默认定义)。父类中的纯虚函数,子类一定要复写它

创建一个子类对象,通过子类对象调用父类函数;

注意父类CDocument中的OnFileOpen函数中的Serialize函数实际上是虚函数,上面没写出来;

在子类CMyDoc中将其进行了重写,通过子类对象调用父类中的OnFileOpen函数,开始执行父类中的OnFileOpen函数,指向到Serialize函数时,发现是虚函数,到子类中找Serialize函数具体的实现。

**总结:**虚函数,将父类中的函数延缓到子类中去决定。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3l328ISj-165709618)(…/…/assets/c++面向对象高级开发-上/image-0224155701867.png)]

12.2、继承+复合的构造和析构顺序

子类中有其他类型+子类自己还是继承的父类; **构造函数:**Base构造函数—>Component构造函数—>Derived构造函数**析构函数:**Derived析构函数—>Component析构函数—>Base析构函数

先构造和析构复合的成员。

子类继承了父类+父类中有其他类型

**构造顺序:**如框图所示(从里到外),先父类中的其他类型构造Component—>父类构造—>子类构造;

**析构顺序:**如框图所示(从外到里),子类析构—>父类析构—>父类中的其他类型析构Component

12.3、委托+继承实例

文件只有一个,窗口有4份。

如果数据有变化,相应的各个表示的图都会跟着变化。

subject:原始的数据,里面可以包含多个Observer指针(委托的形式)

Observer:观察数据,以不同窗口形式进行表示;还是一个父类,可以派生出不同的子类;

**vector<Oberserver*>m_viewers:**准备一个容器来放右边各个不同的Observer,Observer;

**Subject中attach()函数:**将观察者放入Subject中的vector容器中;

**notify():**通知所有的观察者Observer更新数据。

每一个Observer窗口都会来父类进行注册,注销;

**注册:**提供函数放到容器中,进行注册,调用数据;

**注销:**同时还应该进行注销

notify函数(遍历函数):更新数据

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。