依赖关系循环
A dependency loop
我设计了一个继承自CDialog
的对象(称为NBDialog
,以及一些派生的控件对象,如CEdit
、CDateTimeCtrl
、CComboBox
等。NBDialog
是一个项目,控件位于其他项目中。
当然,所有的控件都放在对话框上并使用对话框的方法,所以我必须 #include NBDialog.h
,并为链接器添加其.lib
文件。
我还想处理对话框中的所有这些控件,所以我NBDialog.h
写了以下几行:
class NBCommonEditBox;
class NBDateTimeCtrl;
class NBCommonComboBox;
CMapWordToOb* NBGetEditBoxMap();
NBCommonEditBox* NBGetEditBoxById(unsigned long ID);
CMapWordToOb* NBGetDateTimeMap();
NBDateTimeCtrl* NBGetDateTimeById(unsigned long ID);
CMapWordToOb* NBGetComboBoxMap();
NBCommonComboBox* NBGetComboBoxById(unsigned long ID);
这样NBDialog.h
不知道对象的上下文,但它知道它们存在并将它们存储在地图中。
现在我想扩展NBDialog
项目并添加一个方法,该方法将获取所有控件的打印信息,以便所有从NBDialog
固有的对象都将能够使用此方法。打印信息在控件实现中定义。
编辑:如果我用NBDialog.cpp
编写此方法,我无法编译它,因为NBDialog
不知道控件类的上下文:
CStringList* NBDialog::NBGetMainTexts()
{
CStringList* mainTexts = new CStringList();
POSITION pos;
WORD key;
NBCommonEditBox* currEdit = NULL;
for (pos = this->NBGetEditBoxMap()->GetStartPosition(); pos != NULL;)
{
this->NBGetEditBoxMap()->GetNextAssoc(pos, key, (CObject*&)currEdit);
currEdit->NBStringsToPrint(mainTexts);
}
return mainTexts;
}
有没有办法编写所需的方法?
最简单的方法是为此定义一个接口并添加该接口而不是 CObject。 该接口可以提供一种方法来获取控件本身。 不要害怕多重继承 - 是的,它可能会有轻微的性能损失,但这对你来说不是问题。 在这种情况下,它将类似于 Java 中的接口继承,因为您将使用纯接口。
您也可以以类似的方式实现这一点,以避免多重继承,但它会增加您不需要的更多复杂性。
// Interface goes in the NBDialog project
class INBControl {
public:
virtual ~INBControl() = 0;
virtual CWnd* getWnd() = 0;
virtual void getStringsToPrint(CStringList& strings) = 0;
};
inline INBControl::~INBControl() {}
class NBCommonComboBox : public CComboBox, public INBControl
{
public:
// ... stuff ...
virtual CWnd* getWnd() {
return this;
}
virtual void getStringsToPrint(CStringList& strings) {
strings.AddTail("foo"); // for example
}
};
// NBDialog
#include <map>
class NBDialog : public CDialog
{
public:
// .. stuff ..
private:
typedef std::map<int, INBControl*> ControlMap;
ControlMap control_map_;
};
void NBDialog::addNBControl(INBControl* control, int id)
{
CWnd* wnd = control->getWnd();
// Do stuff with the control such as add it
control_map_[id] = control;
}
// let the caller be responsible for [de]allocation of the string list
void NBDialog::NBGetMainTexts(CStringList& texts)
{
ControlMap::iterator i = control_map_.begin();
ControlMap::iterator e = control_map_.end();
for(; i != e; ++i) {
i->second->getStringsToPrint(texts);
}
}
或者,使用自定义窗口消息并迭代所有控件,向下转换为 CWnd 并在其 HWND 上使用 SendMessage。 每个控件都需要处理自定义窗口界面。 您可以在消息的 LPARAM 中传递指向字符串列表的指针。 此应用程序很灵活,但有些脆弱/不安全,如果您最终意外地将同一消息 ID 用于其他内容,则可能会崩溃。
您的实现文件 ( NBDialog.cpp
( 可以自由#include
必要的标头来完成这项工作(大概是 NBCommonComboBox.h
等( 因为.cpp
文件不是任何东西#include
的,所以你不会引起任何循环包含问题。
- C++GTKMM gui循环依赖关系
- 如何在头文件中声明类模板(由于循环依赖关系)
- C++模板方法中的循环依赖关系
- Wt::D bo 中的循环依赖关系
- 在包含窗口标头时难以解决循环依赖关系问题
- 解决循环依赖关系 c++ 的想法
- C++循环依赖关系,未声明的标识符
- C++ 中的循环依赖关系问题
- CMake 外部和内部静态库的循环依赖关系
- "std::shared_ptr"循环依赖关系是如何导致问题的
- 纯引用而不是weak_ptr来打破循环依赖关系
- "invalid use of incomplete type" .解决循环依赖关系
- C++循环依赖关系
- Cmake生成了VS项目的循环依赖关系,但没有制作文件.如何避免
- 有没有办法解决这个模板循环依赖关系
- 解决使用工厂时的循环依赖关系
- 如何解决此循环依赖关系
- 具有模板专用化的复合结构中的循环依赖关系
- 如果存在任何循环关系,我应该假设弱指针使用吗?
- Qt类及其成员之间的循环关系