OOP与宏观问题

nak*_*iya 11 c++ oop

我今天通过同事遇到了这个问题.他有一个前端系统的设计,如下所示:

class LWindow
{
   //Interface for common methods to Windows
};

class LListBox : public LWindow
{
   //Do not override methods in LWindow.
   //Interface for List specific stuff
}

class LComboBox : public LWindow{} //So on
Run Code Online (Sandbox Code Playgroud)

Window系统应该可以在多个平台上运行.假设目前我们的目标是Windows和Linux.对于Windows,我们有一个接口的实现LWindow.我们有所有LListBoxes,LComboBoxes等的多个实现.我的反应是将一个LWindow*(Implementation对象)传递给基LWindow类,所以它可以这样做:

void LWindow::Move(int x, int y)
{
   p_Impl->Move(x, y);   //Impl is an LWindow*
}
Run Code Online (Sandbox Code Playgroud)

而且,做同样的事情为实施LListBox

最初给出的解决方案有很大不同.归结为:

#define WindowsCommonImpl {//Set of overrides for LWindow methods}

class WinListBox : public LListBox
{
    WindowsCommonImpl     //The overrides for methods in LWindow will get pasted here.
    //LListBox overrides
}

//So on
Run Code Online (Sandbox Code Playgroud)

现在,我已经阅读了所有关于宏的邪恶和良好的设计实践,我立即反对这个计划.毕竟,这是伪装的代码重复.但我无法使我的同事相信这一点.我很惊讶,情况确实如此.所以,我向你提出这个问题.后一种方法可能存在哪些问题?我想要实际的答案.我需要说服一个非常实用的人(并且习惯于做这种事情.他提到MFC中有很多宏!)这很糟糕(和我自己).不教他美学.此外,我提出的建议有什么问题吗?如果是这样,我该如何改进呢?谢谢.

编辑:请给我一些理由让我对自己支持oop感觉良好:(

寻求赏金.请询问您是否需要任何澄清.我想知道针对宏的争论和vs OOP :)

mar*_*han 2

您的同事可能正在考虑 MFC 消息映射宏;这些在每个 MFC 派生类中看起来很重要的地方都使用,因此我可以看到您的同事来自哪里。然而,这些并不是用于实现接口,而是用于与 Windows 操作系统的其余部分交互的细节。

具体来说,这些宏实现了 Windows 消息泵系统的一部分,其中代表 MFC 类执行任务的请求的“消息”被定向到正确的处理程序函数(例如,将消息映射到处理程序)。如果您有权访问 Visual Studio,您将看到这些宏将消息映射条目包装在一个有点复杂的结构数组中(调用操作系统代码知道如何读取),并提供访问此映射的函数。

作为 MFC 用户,宏系统使我们看起来很干净。但这之所以有效,主要是因为底层 Windows API 是明确指定的并且不会发生太大变化,并且大多数宏代码是由 IDE 生成的以避免拼写错误。如果您需要实现涉及混乱声明的东西,那么宏可能有意义,但到目前为止,情况似乎并非如此。

您的同事可能感兴趣的实际问题:

  • 重复的宏调用。看起来您需要将“WindowsCommonImpl”行复制到每个类声明中 - 假设宏扩展为一些内联函数。如果它们只是声明并且实现位于单独的宏中,则您也需要在每个 .cpp 文件中执行此操作 - 并每次更改传递到宏中的类名。
  • 重新编译时间更长。对于您的解决方案,如果您更改 LWindow 实现中的某些内容,您可能只需要重新编译 LWindow.cpp。如果您更改了宏中的某些内容,则包括宏头文件在内的所有内容都需要重新编译,这可能是您的整个项目。
  • 更难调试。如果错误与宏内的逻辑有关,则调试器可能会中断调用者,而您不会立即看到错误。您甚至可能不想检查宏定义,因为您认为您确切地知道它的作用。

所以基本上你的 LWindow 解决方案是一个更好的解决方案,可以最大限度地减少以后的麻烦。