C++ 类之间的互相调用

立马几天举行C++11底线程池时遇到了一个题材,就是类A想要调用类B的法门,而类B也想调用类A的章程

此处为简化起见,我之所以更易理解的观察者模式于大家进行陈述

 

观察者模式:在靶之间定义一针对大多之靠,这样一来,当一个目标改变状态时,依赖它的靶子都见面收通知,并自动更新

C++ 1

观察者模式遭遇来一个subject和observer

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

当subject发生改变时,它打招呼所有的观察者

当一个observer不思当观察者时,它会朝着subject发出请求,将协调从观察者中开

 

在意,在此间是存在一个互调用的

subject肯定得理解observer的法门,这样它们才会于状态有变动时调用observer的法通知他们

若当一个observer想只要将自己于观察者中革除的下,它需保留一个subjet的援,并让subject调用remove方法将自己除名

 

为简化起见

以此间的类图如下

C++ 2

 

每当java,我们可以如此实现

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++ 3

 

而在C++中

若果我们于main.cpp中修出以下代码

#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

C++ 4

立即是以虽然有类的成员的眼前为声明

而是你只可以定义指向这种裂隙的指针或引用,可以声明但无可知定义为这种无完全类型或者返回路的参数

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

设C++是从未有过对类的函数的眼前为声明的

于是我们若起一个办法,让咱们当宣称类Subject时会来看类Observer的宣示

如果在宣称类Observer时,能看到类Subject的声明

 

因此我们想到以Subject和Observer分别放到两个公文被失去

故而我们发矣之类尝试

subject.h

#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

#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

#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

#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

#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

#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方法,有不会见挑起互相包含的问题了

运作结果如下

C++ 5