类成员声明的快捷方式

时间:2013-10-18 17:37:25

标签: c++ coding-style

我必须在课堂上添加一堆成员。我想添加一个像这样的宏:

#define MEMBER(TYPE,NAME) \
    private: TYPE m_##NAME; \
    public: TYPE get##NAME() const { return m_##NAME; } \
    public: void set##NAME(TYPE in##NAME) { m_##NAME = in##NAME; }

然后使用它将成员添加到类中:

class foo {
    MEMBER(std::string, OutputDir);
    MEMBER(int, MaxIterations);
    MEMBER(double, OptimizationCutoff);
    // And a couple dozen more members...
    public:
    // The rest of the class declarations
};

意图显然是要快捷方式的多个代码实例,每个类成员中有3行:

private: std::string m_OutputDir;
public: std::string getOutputDir() const { return m_OutputDir; }
public: void setOutputDir(std::string inOutputDir) { m_OutputDir = inOutputDir; }

对这样的编码是否有任何考虑?

1 个答案:

答案 0 :(得分:4)

首先,我要指出一个观察结果。您在此处定义的宏似乎 完全无用 。我得到你想要做的 - 用一行代码声明一个成员变量和简单的getter和setter方法。

我会反驳:如果你只是用简单的getter& amp;暴露这些成员变量。 setters,为什么不只是使成员变量public并完成它?

  

对这样的编码是否有任何考虑?

是的,关于Evil滥用宏的所有常见问题。让我们来看看这里的一些内容。

您正在创建一种只有您才知道的秘密语言。

代码如下:

class foo {
    MEMBER(std::string, OutputDir);
    MEMBER(int, MaxIterations);
    MEMBER(double, OptimizationCutoff);
    // And a couple dozen more members...
    public:
    // The rest of the class declarations
};

在它的构造中,一目了然可能有点,但是当需要维护或扩展其中一个成员foo时,有许多细节被模糊不清,或者宏本身。

例如,只是看了一遍,我就明白你要声明一个成员OutputDir,但实际上并没有迹象表明它是数据成员还是成员函数。如果它是成员函数,返回类型是什么?有什么参数?我如何声明成员函数模板?什么是模板参数?

你已经在这里构建了一个语法,可以在第一次键入代码时保存一两次击键,但是当有人需要回答任何这些问题时,可能会产生数小时的挫败感和头脑冲击。由于除了您之外没有任何人记录或支持,您的宏最终会类似于只有您知道的秘密语言。

宏很难调试

对使用宏的代码进行标记时,您会看到替换文本 - 而不是宏或调用它的方式。这可能非常令人困惑。

宏没有命名空间

宏是一种强制文本替换工具。它们不尊重任何名称空间或范围,并且在定义和调用它们的任何地方都被普遍应用。这完全围绕C ++类型系统,并允许您编写代码,否则会引起错误。

宏有奇怪和无意的副作用,并且应用于你没想到的地方。

一个常见的例子是VisualStudio对minmax宏的定义,它在标准库中以相同的名称破坏了这些函数。副作用可能很奇怪,如上所述,很难调试。