前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C++ 类之间的互相调用

C++ 类之间的互相调用

作者头像
magicsoar
发布于 2018-02-06 02:50:48
发布于 2018-02-06 02:50:48
2.5K00
代码可运行
举报
文章被收录于专栏:magicsoarmagicsoar
运行总次数:0
代码可运行

这几天做C++11的线程池时遇到了一个问题,就是类A想要调用类B的方法,而类B也想调用类A的方法

这里为了简化起见,我用更容易理解的观察者模式向大家展开陈述

观察者模式:在对象之间定义一对多的依赖,这样一来,当一个对象改变状态时,依赖它的对象都会收到通知,并自动更新

观察者模式中有一个subject和observer

observer向subject注册成为一个观察者

当subject发生改变时,它通知所有的观察者

当一个observer不想作为观察者时,它会向subject发出请求,将自己从观察者中除名

注意,在这里是存在一个互相调用的

subject肯定需要知道observer的方法,这样它才能在状态发生改变时调用observer的方法通知他们

而当一个observer想要将自己从观察者中除名的时候,它需要保留一个subjet的引用,并让subject调用remove方法将自己除名

为了简化起见

在这里的类图如下

在java,我们可以这样实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.util.ArrayList;
class Subject {

    public void change() {
        
         for (Observer x :observerList) { 
             x.Show();
         } 
    }

    public void register(Observer o) {
        observerList.add(o);
    }

    public void Remove(Observer o) {
        observerList.remove(o);
    }

    private ArrayList<Observer> observerList=new ArrayList<Observer>();
}

class Observer {
    public void Show() {
        System.out.println("I konw The Subject is changed");
    }

    public Observer(Subject s) {
        subject = s;
    }

    public void Remove() {
        subject.Remove(this);
    }

    private Subject subject;
}

public class Observertry {

    public static void main(String[] args) {
        Subject s = new Subject();
        Observer o = new Observer(s);
        s.register(o);
        s.change();

    }
}

运行结果

而在C++中

如果我们在main.cpp中编写出以下代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Observer;
class Subject;
class Observer
{
public:

    Observer(Subject *s)
    {
        subject = s;
    }
    void Remove(Subject *s)
    {
        s->Remove(this);
    }
    void Show()
    {
        cout << "I konw Subject is change" << endl;
    }
private:
    Subject *subject;
};
class Subject
{
public:
    void change()
    {
        for (vector<Observer*>::iterator it = observerlist.begin(); it != observerlist.end(); it++)
        {
            (*it)->Show();
        }
        
    }
    void Remove(Observer *o)
    {
        observerlist.erase(find(observerlist.begin(), observerlist.end(), o));
    }
    void Register(Observer *o)
    {
        observerlist.push_back(o);
    }
private:
    vector<Observer*> observerlist;
    
};
int main()
{
    Subject s;
    Observer o(&s);
    s.Register(&o);
    s.change();
    system("pause");
}

会发现这段代码无法编译通过

在vs2013中会有以下error

这是因为虽然有类的成员的前向声明

但你仅可以定义指向这种裂隙的指针或引用,可以声明但不能定义以这种不完全类型或者返回类型的参数

而这里你想要在Observer类里调用subject的方法,而subject是在Observer的后面声明定义的,所以无法调用subject的方法

而C++是没有对类的函数的前向声明的

所以我们要有一个方法,让我们在声明类Subject时能看到类Observer的声明

而在声明类Observer时,能看到类Subject的声明

所以我们想到将Subject和Observer分别放到两个文件中去

所以我们有了如下尝试

subject.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#pragma once
#include "Observer.h"
#include <iostream>
#include <vector>

class Subject
{
public:
    void change();
    void Remove(Observer *o);
    void Register(Observer *o);
    std::vector<Observer*> observerlist;
};

observer.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#pragma once
#include <iostream>
#include "Subject.h"
using namespace std;
class Subject;

class Observer
{
public:
    Observer(Subject *s);
    
    void Remove(Subject *s);
    void Show();
    Subject *subject;
};

但这一次依旧无法通过编译

因为我们这里出现了头文件的互相包含

subject.h中包含了observer.h

observer.h中包含了subject.h

所以正确的方法是把其中的一个的include放到相应的实现文件中即cpp文件中

代码如下

subject.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#pragma once
#include "Observer.h"
#include <iostream>
#include <vector>

class Subject
{
public:
    void change();
    void Remove(Observer *o);
    void Register(Observer *o);
    std::vector<Observer*> observerlist;
};

subject.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "Subject.h"

void Subject::change()
{
    for (vector<Observer*>::iterator it = observerlist.begin(); it != observerlist.end(); it++)
    {
        (*it)->Show();
    }
}

void Subject::Remove(Observer *o)
{
    observerlist.erase(find(observerlist.begin(), observerlist.end(), o));
}
void Subject::Register(Observer *o)
{
    observerlist.push_back(o);
}

observer.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#pragma once
#include <iostream>

using namespace std;
class Subject;

class Observer
{
public:
    Observer(Subject *s);
    
    void Remove(Subject *s);
    void Show();
    Subject *subject;
};

observer.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "Observer.h"
#include "Subject.h"

Observer::Observer(Subject *s)
{
    subject = s;
}

void Observer::Remove(Subject *s)
{
    s->Remove(this);
}
void  Observer::Show()
{
    cout << "I know Subject is changed" << endl;
}

我们将#include “Subject.h”放到了observer.cpp中

这样就在observer的实现中就可以看到Subject的声明,进而调用subject的Remove方法,有不会引起互相包含的问题了

运行结果如下

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
基础知识_设计模式
文章目录 1. 单例模式 1.1. 懒汉式 1.2. 饿汉式 2. Oberver观察者模式 记录一下常见的设计模式的实现方法(Cpp实现)。 单例模式 当只允许类创建一个实例的时候,可以使用单例模式。 懒汉式 懒汉式是在需要创建实例的时候才创建。 将构造函数设置为私有可以组织创建对象,然后通过static函数从内部调用构造函数。 线程不安全 #include <iostream> using namespace std; class Singleton{ public: static Si
yifei_
2022/11/14
2070
C++设计模式——Observer观察者模式
观察者模式是一种行为型设计模式,又被称为"发布-订阅"模式,它定义了对象之间的一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会收到通知并自动更新。
Coder-ZZ
2024/07/01
5180
C++设计模式——Observer观察者模式
如何用C++11实现观察者模式
观察者模式是一种设计模式,定义了对象之间的一对多关系。当一个对象状态发生改变时,它的依赖者都会收到通知并自动更新。在C++11中,可以通过以下方式实现观察者模式:
音视频牛哥
2023/07/08
2220
【C++11】 改进我们的设计模式---观察者模式
观察者模式(Observer Pattern)主要解决的是当对象间存在一对多关系时当一个对象被修改,会自动通知依赖它的其它对象。在设计模式中观察者模式属于行为型模式。
CPP开发前沿
2021/11/16
1.2K0
【C++11】 改进我们的设计模式---观察者模式
【C++】设计模式:观察者、策略、模板
观察者模式的基本原理,通过观察者模式可以实现对象之间的松耦合,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并作出相应的响应。
DevFrank
2024/07/24
1030
Java设计模式之(十二)——观察者模式
观察者模式(Observer Design Pattern):在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会得到通知并自动更新。
IT可乐
2021/12/04
5.3K0
Java设计模式之(十二)——观察者模式
观察者模式 Observer 发布订阅模式 源 监听 行为型 设计模式(二十三)
定义对象一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖他的对象都得到通知并自动更新。
noteless
2018/12/27
6010
C++11 改造观察者模式(参考 In-Depth C++11)
这个示例在 In-Depth C++11 书中有很详细的说明和实现,这里只记录自己关心的部分。传统观察者模式基本上都是要提供一个接口类用于提供观察者继承从而在数据变化时让接口被调用。一个典型的例子如下:
我与梦想有个约会
2023/10/21
2350
C++实现设计模式之观察者模式
观察者模式是一种一对多的以来关系,当一个对象的状态发生改变时,所有依赖于他的对象都得到通知并被自动更新。它的主体是通知的发布者,发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知,将观察者和被观察的对象分离开。
音视频牛哥
2023/07/19
2290
Java 中的观察者模式
----本文来源于Rohit Joshi的《Java Design Patterns》一书的Chapter7:Observer Design Pattern
码农小胖哥
2020/05/08
7660
Java 中的观察者模式
设计模式之观察者模式
观察者模式又称为发布-订阅(Publish/Subscribe)模式,是23种设计模式之一。DP中是这么定义观察者模式的:
端碗吹水
2020/09/23
4820
设计模式之观察者模式
“牵一发而动全身”——我用观察者模式简单模拟吃鸡
每当Jungle更新发布了文章,作为Jungle的关注者,你会第一时间接到消息,(如果)然后就可以去查看、点赞、评论和转发,接下来的一天你都高高兴兴;
用户6557940
2022/07/24
3210
“牵一发而动全身”——我用观察者模式简单模拟吃鸡
观察者模式
  有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
小小工匠
2021/08/16
7660
设计模式之观察者模式
观察者模式定义了对象之间一种一对多的关系,即一个对象发生改变的时候,会通知其他相关的对象。
丁D
2022/08/12
1690
设计模式之观察者模式
设计模式学习笔记(十九)观察者模式及应用场景
观察者模式(Observer Design Pattern),也叫做发布订阅模式(Publish-Subscribe Design Pattern)、模型-视图(Model-View)模式、源-监听器(Source-Listener)模式、从属者(Dependents)模式。指在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。
归思君
2023/10/16
4360
设计模式学习笔记(十九)观察者模式及应用场景
C++17中weak_from_this详解
weak_from_this 是 std::enable_shared_from_this 类模板的一个成员函数,其核心作用是获取当前对象的 std::weak_ptr。与 shared_from_this 不同,weak_from_this 返回的 std::weak_ptr 不会增加对象的引用计数。这一特性使得它在处理对象生命周期管理时具有独特的优势。
码事漫谈
2025/02/01
1290
C++17中weak_from_this详解
观察者模式实战:真实项目中屡试不爽的瓜娃EventBus到底如何实现观察者模式的?
最近项目在对接神策埋点相关需求。 有一个场景是:产品自定义了很多埋点事件,有些事件需要后端进行一定的业务处理,然后进行埋点。
一枝花算不算浪漫
2020/04/27
1.2K0
观察者模式实战:真实项目中屡试不爽的瓜娃EventBus到底如何实现观察者模式的?
一文带你彻底搞懂发布与订阅设计
我们常说的发布订阅设计模式,也叫观察者模式,也就是事件监听机制,观察者模式订阅了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当这个主题对象发生改变时,会通知所有的观察者对象,使他们能够自动的更新自己!
Java极客技术
2022/12/02
6800
一文带你彻底搞懂发布与订阅设计
观察者模式
一、简介 1、观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化的时候,会通知所有观察者对象,使它们能够动态的更新自己。 如:图形界面的工具箱中,表格对象和柱状图对象使用不同的形式描述同一应用数据对象的信息。表格对象和柱状图对象相互并不知道对方的存在,但是当用户改变表格中的信息的时候,柱状图也应该立即反映这一变化,反过来也如此。这意味着表格对象和柱状图对象都依赖于数据对象,数据对象的任何改变都应该立即通知它们。所以这个例子中表格和柱状图就是两个观察者,而数
用户1215536
2018/02/05
6080
观察者模式
观察者模式
观察者模式(Observer Pattern)是一种行为型设计模式,用于定义对象间的一对多依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会自动收到通知并更新。这种模式主要用于实现发布-订阅机制。
码事漫谈
2024/12/20
1450
观察者模式
相关推荐
基础知识_设计模式
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验