先贴上部分代码:

#include "stdafx.h"
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Observer;
class Subject;
class Subject
{
public:
Subject()
{
msg="orinal msg";
}
void add(Observer* ob)
{
vec.push_back(ob);
}
void show()
{
cout<<"broadcast:msg is:"<<msg<<endl;
}
void change(string msg)
{
this->msg=msg;
notification();
}
void notification()
{
vector<Observer*>::iterator v = vec.begin();
while( v != vec.end()) {
(*v)->Showdate();
v++;
}
} private:
vector<Observer*> vec;
string msg; };
class Observer
{
public:
Observer(Subject* sub)
{
this->sub=sub;
this->sub->add(this);
}
void Showdate()
{
sub->show();
}
private:
Subject* sub;
};

说明一下:这么写编译会报错的!

在 notification() 这一行报了错:
:错误 1 error C2027: 使用了未定义类型“Observer”

:错误 2 error C2227: “->Showdate”的左边必须指向类/结构/联合/泛型类型

我刚写的时候也是很疑问,为什么会这样呢,经过一番研究,原来编译过不去的原因是因为,在notification()函数里面调用了Observer类里的方法showdate(),而这个方法的声明在notification()之后,所以编译器找不到.  

需要注意的一点是:虽然已经在开头声明了class Observer; class Subject;这两个类,但是 也仅仅是声明了类,并不代表声明了类里的函数。由于函数声明的位置不同 编译器仍有找不到的可能。

所以可以这么解决:

#include "stdafx.h"
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Observer;
class Subject;
class Subject
{
public:
Subject()
{
msg="orinal msg";
}
void add(Observer* ob)
{
vec.push_back(ob);
}
void show()
{
cout<<"broadcast:msg is:"<<msg<<endl;
}
void change(string msg)
{
this->msg=msg;
notification();
}
void notification();
private:
vector<Observer*> vec;
string msg; };
class Observer
{
public:
Observer(Subject* sub)
{
this->sub=sub;
this->sub->add(this);
}
void Showdate()
{
sub->show();
}
private:
Subject* sub;
};
void Subject::notification()
{
vector<Observer*>::iterator v = vec.begin();
while( v != vec.end()) {
(*v)->Showdate();
v++;
}
}

可以看到,把notification这个方法声明到最后就可以了。

通过写这个观察者模式,我有些收获:

C++毕竟与JAVA不同,在JAVA里不会存在这些问题(不得不说JAVA在类和对象这个方面有很多东西做的确实比C++强上不少)

所以写C++时先定义类 再声明函数,尽量不要在类内就把函数写好。写的时候一定要注意:先声明的函数是否调用了后声明的函数。

PS:说下C++的this指针,this指针可以理解为指向这个对象本身的指针。

附上主函数:

int _tmain(int argc, _TCHAR* argv[])
{
Subject* sub=new Subject();
Observer* ob1=new Observer(sub);
Observer* ob2=new Observer(sub);
Observer* ob3=new Observer(sub);
   char opt;
while(true)
{
string tempmsg;
cout<<"please input a number"<<endl;
cin>>opt;
switch(opt)
{
case '1':
cout<<"please input the change msg"<<endl;
cin>>tempmsg;
sub->change(tempmsg);
break;
default:
break;
}
}
return ;
}

说下观察者模式的作用:

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

就拿我这个程序来说:可以把Subject看作一个水位监测,Observer看作显示水位状态的屏幕。 一旦监测(Subject)到水位发生变化 屏幕(Observer)立刻显示改变后的水位状态。

优点:

观察者和被观察者是一套触发机制:保证高度的协作;

缺点:

一个缺点:观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

以上只是我的愚见,如果有些地方有误欢迎批评指正 oO(AIA)Oo

设计模式一:关于C++写观察者模式的一些收获的更多相关文章

  1. 设计模式之第18章-观察者模式(Java实现)

    设计模式之第18章-观察者模式(Java实现) 话说曾小贤,也就是陈赫这些天有些火,那么这些明星最怕的,同样最喜欢的是什么呢?没错,就是狗仔队.英文的名字比较有意思,是paparazzo,这一说法据说 ...

  2. .NET设计模式(19):观察者模式(Observer Pattern)(转)

    概述 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系” ——一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知.如果这样的依赖关系过于紧密,将使软件不能很好地抵御 ...

  3. 设计模式----行为型模式之观察者模式(Observer Pattern)

    下面是阅读<Head First设计模式>的笔记. 观察者模式 定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新. JDK API内置机制 ...

  4. IOS设计模式之三(适配器模式,观察者模式)

    本文原文请见:http://www.raywenderlich.com/46988/ios-design-patterns. 由 @krq_tiger(http://weibo.com/xmuzyq) ...

  5. c++设计模式总结 好久没写博客了 实在是忙

    具体代码就不贴出来了   通俗易懂的理解方式      原创 c++设计模式: 简单工厂模式 工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个个产品:在工厂中加工产品 ...

  6. C#设计模式学习笔记:(16)观察者模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7928521.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第四个模式--观 ...

  7. c++ 设计模式5 (Observer / Event 观察者模式)

    3.3 观察者模式 (Observer)/发布-订阅模式 动机: 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”——一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都能得 ...

  8. 设计模式总结(Java)—— 观察者模式

    概述 它用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应.在观察者模式中,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多 ...

  9. java23种设计模式之: 策略模式,观察者模式

    策略模式  --老司机开车,但是他今天想到路虎,明天想开奔驰...针对他不同的需求,来产生不同的应对策略    策略类是一个接口,定义了一个大概的方法,而实现具体的策略则是由实现类完成的,这样的目的是 ...

随机推荐

  1. jquery控制图片切换

    这种js现在用的很多.同时网上的js代码页很多.我直接从网上当了一个来用:代码如下: html <div class="bannerbox">              ...

  2. 【转】JDBC学习笔记(6)——获取自动生成的主键值&处理Blob&数据库事务处理

    转自:http://www.cnblogs.com/ysw-go/ 获取数据库自动生成的主键 我们这里只是为了了解具体的实现步骤:我们在插入数据的时候,经常会需要获取我们插入的这一行数据对应的主键值. ...

  3. Unity Debug类

    静态变量 developerConsoleVisible 报告是否开发控制台是可见的.开发控制台不能出现使用: isDebugBuild 在构建设置对话框中有一个叫做"发展构建"复 ...

  4. java OJ题目判断输入结束(与C语言的EOF结束等价)

    /* * java 作Oj题目是会有输入若干数据的情况,不好判断输入结束符, * 类似于C语言中的EOF符号 * 在这里提供了一种方法 * */ import java.util.Iterator; ...

  5. JAVAEE规范基础知识

    JavaEE规范基础知识 本人博客文章网址:https://www.peretang.com/basic-knowledge-of-javaee-standard/ JavaEE简介 JavaEE,J ...

  6. final的用法

    先来看一段代码 class Car extends Vehicle {     public static void main (String[] args)     {         new  C ...

  7. MongoDB副本集的搭建

    副本集是mongodb提供的一种高可用解决方案.相对于原来的主从复制,副本集能自动感知primary节点的下线,并提升其中一个Secondary作为Primary. 整个过程对业务透明,同时也大大降低 ...

  8. Windows10 图标重建

    Windows10 图标重建 有没有遇到电脑上某个图标成了黑块,白块或者没有图呢. 那这样的话就可以使用图标重建啦. 删掉Windows10的图标文件如下图 路径: %userprofile%\App ...

  9. Linux下安装Oracle的两种方式------有图形界面安装和静默安装

    本文参考文章 http://blog.csdn.net/zonej/article/details/50680857 http://blog.csdn.net/tongzidane/article/d ...

  10. angular2项目添加ng2-bootstrap

    1. 先webstome创建一个空的工程.例如test File--> New -->Project --> Empty Project 2.然后命令行(Alt+F12)下执行以下命 ...