C++实现MVC模式

使用VS进行开发  新建空项目 分别添加头文件 源文件就可以了

头文件


ControllerBase.h

<span style="font-family:KaiTi_GB2312;font-size:18px;">#pragma once

class Observer;
class ModelBase;
class ControllerBase
{
public:
	ControllerBase(void){};
	virtual ~ControllerBase(void){};
	virtual void Register(ModelBase* model, Observer* observer) = 0;
};
</span>

ModelBase.h

<span style="font-family:KaiTi_GB2312;font-size:18px;">#pragma once

class Observer;

class ControllerBase;
class PrintController;

class ModelBase
{
public:
	ModelBase(void){};
	virtual ~ModelBase(void){};
	
private:
	friend ControllerBase;
	friend PrintController;
	virtual void Attach(Observer * observer) = 0;
	virtual void Detach(Observer * observer) = 0;
	virtual void Notify() = 0;
};
</span>

Observer.h

<span style="font-family:KaiTi_GB2312;font-size:18px;">#pragma once

class ModelBase;
class Observer
{
public:
	Observer(void){};
	virtual ~Observer(void){};
	virtual void Update(ModelBase * model) = 0;
};
</span>

PrintController.h

<span style="font-family:KaiTi_GB2312;font-size:18px;">#pragma once
#include "controllerbase.h"
#include <string>

class PrintModel;
class PrintController :
	public ControllerBase
{
public:
	PrintController(PrintModel* model);
	virtual ~PrintController(void);

	virtual void Register(ModelBase* model, Observer* observer);

	void HandleUserInput(const std::wstring* inputstr);
private:
	PrintModel* model_;
};
</span>

PrintModel.h

<span style="font-family:KaiTi_GB2312;font-size:18px;">#pragma once
#include "modelbase.h"
#include <list>
#include <string>

class PrintController;
class PrintModel :
	public ModelBase
{
public:
	PrintModel(void);
	virtual ~PrintModel(void);
	void GetPrintString(std::wstring& str);

private:
	friend PrintController;
	virtual void Attach(Observer * observer);
	virtual void Detach(Observer * observer);
	virtual void Notify();
	
	void SetPrintString(const std::wstring* str);
	
private:
	std::list<Observer*> observerlist_;
	std::wstring printstring_;
};
</span>

PrintView.h

<span style="font-family:KaiTi_GB2312;font-size:18px;">#pragma once
#include "viewbase.h"
#include "observer.h"
#include "threadbase.h"
#include "taskbase.h"


class PrintModel;
class PrintView;
class PrintTask
	:public TaskBase
{
public:
	PrintTask(PrintView* view, PrintModel* model);
	virtual void DoTask();

private:
	PrintView* view_;
	PrintModel* model_;
};

class PrintView :
	public ViewBase,public Observer,public ThreadBase
{
public:
	PrintView(PrintModel* model);
	virtual ~PrintView(void);

	virtual void Update(ModelBase * model);

	virtual void HandleTask(TaskBase* task);

private:
	friend PrintTask;
	void DoUpdate(ModelBase * model);
private:
	PrintModel* model_;
};
</span>

stdafx.h

<span style="font-family:KaiTi_GB2312;font-size:18px;">// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>



// TODO: 在此处引用程序需要的其他头文件
</span>

targetver.h

<span style="font-family:KaiTi_GB2312;font-size:18px;">#pragma once

// 以下宏定义要求的最低平台。要求的最低平台
// 是具有运行应用程序所需功能的 Windows、Internet Explorer 等产品的
// 最早版本。通过在指定版本及更低版本的平台上启用所有可用的功能,宏可以
// 正常工作。

// 如果必须要针对低于以下指定版本的平台,请修改下列定义。
// 有关不同平台对应值的最新信息,请参考 MSDN。
#ifndef _WIN32_WINNT            // 指定要求的最低平台是 Windows Vista。
#define _WIN32_WINNT 0x0600     // 将此值更改为相应的值,以适用于 Windows 的其他版本。
#endif
</span>

TaskBase.h

<span style="font-family:KaiTi_GB2312;font-size:18px;">#pragma once

class TaskBase
{
public:
	TaskBase(void){};
	virtual ~TaskBase(void){};

	virtual void DoTask() = 0;
};
</span>

ThreadBase.h

<span style="font-family:KaiTi_GB2312;font-size:18px;">#pragma once
#include <windows.h>
#include <queue>

#define MAX_TASK_COUNT 1024
class TaskBase;
class ThreadBase
{
public:
	ThreadBase(void);
	virtual ~ThreadBase(void);

	// 使线程正常运行,读取消息并按任务提交处理
	void Run();

	// 提供终止线程的入口
	void Terminate();

	// 提交异步任务给该线程操作
	bool PostTaskThread(TaskBase* task);

	// 执行任务


	virtual void HandleTask(TaskBase* task) = 0;

	static DWORD WINAPI ThreadProc(LPVOID lpParameter);
private:
	HANDLE thread_;
	DWORD threadid_;

	// 任务队列
	std::queue<TaskBase*> taskqueue_;
	CRITICAL_SECTION cs_;
	HANDLE semaphore_;

	
	bool runflag_;
};
</span>

ViewBase.h

<span style="font-family:KaiTi_GB2312;font-size:18px;">#pragma once

class ViewBase
{
public:
	ViewBase(void){};
	virtual ~ViewBase(void){};
};
</span>


源文件

MVCDemo.cpp

<span style="font-family:KaiTi_GB2312;font-size:18px;">// MVCDemo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "PrintController.h"
#include "PrintModel.h"
#include "PrintView.h"
#include <iostream>

using std::wcin;
using std::endl;

int _tmain(int argc, _TCHAR* argv[])
{

	
	PrintModel model;
	PrintController controller(&model);
	PrintView view(&model);
	controller.Register(&model,&view);

	view.Run();
	std::wstring str;

	while (1)
	{
		wcin>>str;
		controller.HandleUserInput(&str);
	}

	return 0;
}
</span>

PrintController.cpp

<span style="font-family:KaiTi_GB2312;font-size:18px;">#include "PrintController.h"
#include "PrintModel.h"

PrintController::PrintController(PrintModel* model)
:model_(model)
{
}

PrintController::~PrintController(void)
{
}

void PrintController::Register(ModelBase* model, Observer* observer)
{
	model->Attach(observer);
	return;
}


void PrintController::HandleUserInput(const std::wstring* inputstr)
{
	model_->SetPrintString(inputstr);
	model_->Notify();
	return;
}
</span>

PrintModel.cpp

<span style="font-family:KaiTi_GB2312;font-size:18px;">#include "PrintModel.h"
#include "Observer.h"

PrintModel::PrintModel(void)
{
}

PrintModel::~PrintModel(void)
{
}

void PrintModel::Attach(Observer * observer)
{
	observerlist_.push_front(observer);
}

void PrintModel::Detach(Observer * observer)
{
	observerlist_.remove(observer);
}

void PrintModel::Notify()
{
	std::list<Observer*>::iterator it = observerlist_.begin();
	while (it != observerlist_.end())
	{
		(*it)->Update(this);
		++it;
	}
	return;
}

void PrintModel::GetPrintString(std::wstring& str)
{
	str = printstring_;
}

void PrintModel::SetPrintString(const std::wstring* str)
{
	printstring_ = *str;
}</span>

PrintView.cpp

<span style="font-family:KaiTi_GB2312;font-size:18px;">#include "PrintView.h"
#include "PrintModel.h"
#include <string>
#include <iostream>

using std::endl;
using std::wcout;
using std::wstring;

PrintTask::PrintTask(PrintView* view, PrintModel* model)
	:view_(view),model_(model)
{
}

void PrintTask::DoTask()
{
	view_->DoUpdate(model_);
	return;
}


PrintView::PrintView(PrintModel* model)
	:model_(model)
{
}

PrintView::~PrintView(void)
{
}

void PrintView::Update(ModelBase * model)
{
	if (model_==model)
	{
		PrintTask *task = new PrintTask(this, model_);
		PostTaskThread(task);
	}
	return;
}

void PrintView::DoUpdate(ModelBase * model)
{
	if (model_==model)
	{
		wstring str;
		model_->GetPrintString(str);
		wcout<<str<<endl;
	}
	return;
}

void PrintView::HandleTask(TaskBase* task)
{
	wcout<<L"this is calling PrintView::HandleTask"<<endl;//在页面上显示
	PrintTask* printtask = (PrintTask*)task;
	printtask->DoTask();
}</span>

stdafx.cpp

<span style="font-family:KaiTi_GB2312;font-size:18px;">// stdafx.cpp : 只包括标准包含文件的源文件
// MVCDemo.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息

#include "stdafx.h"

// TODO: 在 STDAFX.H 中
// 引用任何所需的附加头文件,而不是在此文件中引用
</span>

ThreadBase.cpp

<span style="font-family:KaiTi_GB2312;font-size:18px;">#include "ThreadBase.h"
#include <string>
#include <iostream>

using std::wcout;
using std::wstring;
using std::endl;

ThreadBase::ThreadBase(void)
	:runflag_(false)
{
	thread_ = ::CreateThread(NULL,
							0,
							ThreadBase::ThreadProc,
							this,
							CREATE_SUSPENDED,
							&threadid_);

	semaphore_ = ::CreateSemaphore(NULL, MAX_TASK_COUNT, MAX_TASK_COUNT, NULL);

	InitializeCriticalSection(&cs_);
}

ThreadBase::~ThreadBase(void)
{
	DeleteCriticalSection(&cs_);
}

// 需要把list的操作搞成线程安全的
void ThreadBase::Run()
{
	runflag_ = true;
	ResumeThread(thread_);
	return;
}

void ThreadBase::Terminate()
{
	runflag_ = false;
	return;
}

// 提交异步任务给该线程操作
bool ThreadBase::PostTaskThread(TaskBase* task)
{
	WaitForSingleObject(semaphore_,INFINITE);//暂不处理返回错误,这里应该同时等待退出线程的通知

	EnterCriticalSection(&cs_);
	taskqueue_.push(task);
	LeaveCriticalSection(&cs_);

	return false;
}

DWORD ThreadBase::ThreadProc(LPVOID lpParameter)
{
	ThreadBase* threadbase = (ThreadBase*)(lpParameter);
	threadbase->runflag_ = true;
	while(threadbase->runflag_)
	{
		EnterCriticalSection(&threadbase->cs_);
		if (!threadbase->taskqueue_.size())
		{
			LeaveCriticalSection(&threadbase->cs_);
			continue;
		}

		// 从任务队列取出任务处理
		TaskBase* task = threadbase->taskqueue_.front();
		threadbase->taskqueue_.pop();
		LeaveCriticalSection(&threadbase->cs_);

		if (!ReleaseSemaphore( threadbase->semaphore_, 1, NULL) )
		{
			printf("ReleaseSemaphore error: %d\n", GetLastError());
		}
		threadbase->HandleTask(task);
		delete task;
	}
	return 0;
}</span>









  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值