闲来无事,想学习学习C++,就随手写了个简单的观察者模式,代码如下:
头文件:
observer.h
#pragma once
#include <iostream>
#include <memory>
#include <list>
//观察者接口
class IObserver
{
public:
virtual void work() = 0;
virtual ~IObserver() {}
};
using pObserver = std::shared_ptr<IObserver>;
//被观察者接口
class ISubject
{
public:
virtual void attach(pObserver obs) = 0;
virtual void remove(pObserver obs) = 0;
virtual void notify() = 0;
virtual ~ISubject() {}
};
//被观察者
class CMaster : public ISubject
{
public:
void attach(pObserver obs)override;
void remove(pObserver obs)override;
void notify()override;
private:
std::list<pObserver> m_listObs;
};
class CBranch1 :public IObserver
{
public:
explicit CBranch1()
{
m_pData = nullptr;
}
CBranch1(const CBranch1 &)
{
std::cout << "CBranch1 copy construct.\n";
}
CBranch1(const int size)
:m_pData(new int[size])
{
std::cout << "CBranch1 construct.\n";
}
~CBranch1()
{
if (m_pData)
{
delete[] m_pData;
m_pData = nullptr;
std::cout << "CBranch1 deconstruct.\n";
}
}
public:
void work();
private:
void implement();
private:
int *m_pData;
};
class CBranch2 :public IObserver
{
public:
void work();
private:
void implement();
};
源文件:
observer.cpp
#include "Observer.h"
void CMaster::attach(const pObserver obs)
{
m_listObs.push_back(obs);
}
void CMaster::remove(const pObserver obs)
{
auto pos = std::find(m_listObs.begin(), m_listObs.end(), obs);
if (pos != m_listObs.end())
{
m_listObs.remove(obs);
}
}
void CMaster::notify()
{
for (const auto& e : m_listObs)
{
e->work();
}
}
void CBranch2::work()
{
implement();
}
void CBranch2::implement()
{
int count = 0;
while (count < 20)
{
count++;
if (count % 2 == 0)
std::cout << "Branch2 implement()\n";
}
}
void CBranch1::work()
{
implement();
}
void CBranch1::implement()
{
int count = 20;
while (--count)
{
if (count % 2 == 0)
std::cout << "Branch1 implement()\n";
}
}
main.cpp
#include "Observer.h"
int main()
{
//CBranch1 cb1(10);
CBranch1 cb1;
CBranch2 cb2;
CMaster cm;
cm.attach(std::make_shared<CBranch1>(cb1));
cm.attach(std::make_shared<CBranch2>(cb2));
cm.notify();
getchar();
return 0;
}
为了省事,给观察者类包了个智能指针,所以在使用时,通过make_shared传一个智能指针对象进入被观察者的List中,但是这里我遇到了问题,程序跑完的结果如下:
再按回车之后就会出现:
经过一番调试发现:make_shared函数使用时会调用使用对象类的拷贝构造函数,而再拷贝构造函数被调用后,CBranch1 类中的被置空了的data指针又不知怎么地,被赋予了一个莫名其妙的值(0xcdcdcd),这就导致在最后析构时,这个为空的指针又被delete了一次,从而导致了程序异常,我在拷贝构造中,又加了一句:
m_pData = nullptr;
才解决了问题。
有没有大佬懂这个问题的,求传授解惑!