C++开发中一个解决方案里,两个项目的相互引用,相互依赖的实现方法(解决方法)
https://blog.csdn.net/u011450490/article/details/50001887
visual studio项目,C++一个解决方案里不同的项目之间不能相互依赖吗?
众所周知,在一个visual studio solution种可能由多个project组成,这些project会存在依赖关系。规定每个project是一个模块,所有的模块都是单向的依赖方式。比如界面模块依赖于操作模块,操作模块依赖于数据模块.
也就是说。A项目依赖于B项目的情况下(A项目调用B项目的类,函数),B项目是没办法#include A项目中的类的(即B项目没办法包含A项目的类,从而调用A项目的类和方法,否则的话B项目也就依赖于A项目了,而A项目与B项目之间是不能相互依赖的)。
那么,如果我们在编写C++项目时,出现耦合的现象呢。比如说,界面模块A依赖于操作模块B,但是在设计过程中,我发现操作模块B需要用到界面模块A的数据,或者说界面A与操作B一定要有交互,这时候就没办法解决了吗?
在项目编写过程中,我们的项目中出现了相互依赖的问题。经过讨论研究,最终实现了项目之间的相互依赖。有需要的朋友可以看一下,在这里分享给大家。
项目前提是:界面项目A依赖于操作项目B,但是操作项目B中发现一定要调用界面项目A中的对话框,并且要将操作项目B包含类的数据通过A中的对话框进行修改(项目B依赖于项目A,反向依赖了)。实现方法如下:
一、在操作项目B中定义一个UI管理的基类OperationUIManager ,并定义一个纯虚函数ShowDialogSetWallSize(OperationDrawWall* operadrawwall) ,其中OperationDrawWall* operadrawwall是操作项目B中某一个Class的指针。然后定义一个Static静态的基类OperationUIManager的指针static OperationUIManager* m_pOperationUIManager 初始化为NULL(注意:这个地方是关键。m_pOperationUIManager初始为NULL,类OperationUIManager在B项目中是没办法被指向的,也就是分配一块全局的内存给OperationUIManager的指针。具体实现指向要在项目A中实现,接下来会讲)
.h
-
class HOUSE_OPERATION_DLL OperationUIManager
-
{
-
public:
-
OperationUIManager(){}
-
protected:
-
static OperationUIManager* m_pOperationUIManager;
-
public:
-
virtual void ShowDialogSetWallSize(OperationDrawWall* operadrawwall) =0;
-
static OperationUIManager* GetManager();
-
};
.cpp
-
OperationUIManager* OperationUIManager::m_pOperationUIManager = NULL;
-
OperationUIManager* OperationUIManager::GetManager()
-
{
-
return m_pOperationUIManager;
-
}
二、由于界面项目A是依赖于操作项目B的,那么我们在项目A中定义一个继承自项目B中的基类OperationUIManager的一个子类DesignUIManger,并在子类DesignUIManger中实现项目B类OperationDrawWall与项目A中对话框SetWallSizeDialog的数据交互。
这里我们采用单例模式给子类DesignUIManger分配一块全局的内存,(单例模式是什么,不明白的朋友可以自己百度一下)。
首先,由于在项目B中的父类OperationUIManager中我们定义了一个初始为NULL的父类指针static OperationUIManager* m_pOperationUIManager ,我们需要在项目A中对这个父类指针进行赋值,将子类指针New出来的地址赋给父类指针OperationUIManager::m_pOperationUIManager = this;(这句话的含义是:我在项目A中New出一块子类的内存,并将这个子类的内存地址给父类的指针,这样才能在项目B中通过纯虚函数调用项目A的虚函数,也就是实现了反向依赖)实例化DesignUIManger的位置我是放在了MainFrame的构造函数里,需要使用的朋友可以自己设置位置。
其次,我们在父类OperationUIManager中定义过一个纯虚函数virtual void ShowDialogSetWallSize(OperationDrawWall* operadrawwall) =0;现在,我们已经获得OperationUIManager* m_pOperationUIManager指向子类DesignUIManger的指针了。这时候,我们就可以通过项目B中OperationUIManager的纯虚函数ShowDialogSetWallSize(OperationDrawWall* operadrawwall)将项目B中类OperationDrawWall的指针传递到项目A中,并在项目A中实现数据交互。代码如下:
单例模式
.h
-
template<class T>
-
class SingletonInterface
-
{
-
public:
-
static T* GetInstance()
-
{
-
m_bSingletonCreating = true;
-
static T singleton;
-
m_bSingletonCreating = false;
-
return &singleton;
-
}
-
protected:
-
SingletonInterface() {}
-
SingletonInterface(const SingletonInterface&);
-
SingletonInterface& operator=(const SingletonInterface&);
-
static bool m_bSingletonCreating;
-
};
-
template<class T> bool SingletonInterface<T>::m_bSingletonCreating = false;
.cpp
-
#include "stdafx.h"
-
#include "HouseData/SingletonInterface.h"
项目A中的子类
.h
-
class OperationDrawWall;
-
class DesignUIManger :public SingletonInterface<DesignUIManger>,public OperationUIManager
-
{
-
private:
-
DesignUIManger();
-
DesignUIManger(const DesignUIManger&);
-
DesignUIManger& operator=(const DesignUIManger&);
-
friend class SingletonInterface<DesignUIManger>;
-
public:
-
virtual void ShowDialogSetWallSize(OperationDrawWall* operadrawwall);
-
};
.cpp
-
void DesignUIManger::ShowDialogSetWallSize(OperationDrawWall* operadrawwall)
-
{
-
SetWallSizeDialog setsizedlg(operadrawwall);
-
setsizedlg.DoModal();
-
}
-
DesignUIManger::DesignUIManger()
-
{
-
OperationUIManager::m_pOperationUIManager = this;
-
}
然后我在界面项目A中MainFrame里实例化子类的代码是:
DesignUIManger* m_pDesignUIManager = DesignUIManger::GetInstance();
纯粹是单例模式,然后实例化并获取全局内存区的指针。
在项目B中OperationDrawWall类里,我调用基类的代码是:
OperationUIManager::GetManager()->ShowDialogSetWallSize(this);
这里this就是OperationDrawWall的指针,相当于将项目B的指针传到了项目A中,与项目A实现数据交互。
总结,这种实现相互依赖的方法,严格来说没有打破C++项目单向依赖的规则,层次关系上,被依赖的项目B依然是项目A的父级,不同的是,通过子级A对父级B的指针m_pOperationUIManager进行了重新赋值,父级(也就是B)也就获得到了子级A的类的指针(实现反向依赖),并在子级A里实现了数据交互。
真是好大一盘棋,需要的朋友可以自己研究一下,欢迎指教。