1

目前我正在创建一个带有 set 和 get 函数的基类。但是我想添加更复杂的宏,但是宏对于调试来说真的很糟糕,所以我想用模板来做,但我不知道有人知道一本书或链接给我。

我真正的问题要复杂得多,我只是创建了一个集合并获取示例来演示该问题。

作为一个简单的示例,请参见:

#include <iostream>

#define SETGET_BEGIN(name) \
  class name##Base { \
  public: name##Base(){};

#define SETGET_VAR(type,name) \
  protected: type name##_; \
  public: void set##name(const type &_r) {name##_ = _r;} ; \
  public: const type &get##name() const {return name##_; };  \

#define SETGET_END };

SETGET_BEGIN(MyClass)
SETGET_VAR(int,NrA)
SETGET_VAR(float,NrB)
SETGET_END

class MyClass : public MyClassBase {
  public: 
    MyClass() : MyClassBase() {};
};

int main(int argc, char **argv) {
    MyClass myclass;
    myclass.setNrA(4);    
    return 0;
}
4

4 回答 4

3

尽管宏不是 C++ 的最大特性,但由于范围问题、调试限制和其他可能的意外,它们确实偶尔使用。由于宏是文本替换器,它们的优势之一是可以使用文本输入创建代码,如您的示例中所做的那样。

我看不到您制作“动态”类的方法的附加值,但类似的方法可能可用于枚举值或其他重复代码的序列化或值检查。宏也可用于记录以获取文件名/行号/函数名/...

因此,正如 Gumik 已经评论的那样,我看不出如何使用模板来做到这一点。

于 2012-04-26T09:39:24.857 回答
1

您可以使用模板 mixin 组合不同类型的 setter 和 getter。模板混合定义了一个从其模板参数继承的类。这是您使用 mixins 而不是宏的示例:

class MyBaseClass {
public:
    MyBaseClass() {}
};

template<class B> class SetGetNrA : public B {
private:
    int NrA;
public:
    void setNrA(int NrA) { this->NrA = NrA; }
    int getNrA() { return NrA; }
};

template<class B> class SetGetNrB : public B {
private:
    float NrB;
public:
    void setNrB(float NrB) { this->NrB = NrB; }
    float getNrB() { return NrB; }
};

现在使用它:

typedef SetGetNrA<SetGetNrB<MyBaseClass> > MyClass;
MyClass myclass;
myclass.setNrA(4);

您也可以将变量的类型设为模板参数,但如果您希望变量的名称作为参数,则必须使用宏。尽管如此,与仅使用宏替换相比,在模板中做更多的工作可以确保您从一个好的编译器 (clang++) 获得更好的错误消息。

于 2012-04-26T20:26:09.927 回答
0

最简单的解决方案是std::tuple. 它包含您需要的所有功能,名称除外。而不是setnrA(int)元组方法将是set<1>(int). 显然,您可以添加一个枚举来为元组索引分配有意义的名称,因此您可以调用.set<nrA>(4)

于 2012-04-26T09:56:32.513 回答
0

我建议您看一看《现代 C++ 设计:应用的通用编程和设计模式》一书。特别是“基于策略的类设计”一章可能会给你一些想法。不过,我不知道它是否符合您的确切需求。

于 2012-04-26T17:09:48.597 回答