目前我正在创建一个带有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;
}
答案 0 :(得分:3)
即使宏不是C ++的最大特性,但由于范围问题,调试限制和其他可能的意外,它们偶尔也会使用。他们的优势之一,因为宏是文本替换者,可以使用文本输入创建代码,如您的示例所示。
我没有看到制作“动态”类的方法的附加价值,但类似的方法可用于枚举值或其他重复代码的序列化或值检查。宏也可以用于记录以获取文件名/ linenumber / functionname /...
所以,正如Gumik已经评论过的那样,我看不出你如何用模板做到这一点。
答案 1 :(得分:1)
您可以使用模板mixin组合不同类型的setter和getter。模板mixins定义一个继承自其模板参数的类。以下是使用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 ++)获得比仅使用宏替换更好的错误消息。
答案 2 :(得分:0)
最简单的解决方案是std::tuple
。它包含您需要的所有功能,名称除外。元组方法不是setnrA(int)
,而是set<1>(int)
。显然你可以添加一个枚举来为元组索引分配有意义的名字,这样你就可以调用.set<nrA>(4)
答案 3 :(得分:0)
我建议你看看“现代C ++设计: 应用的通用编程和设计模式“。具体而言,”基于策略的类设计“一章可能会给你一些想法。 不过,我不知道它是否符合您的确切需求。