我最近看到一些使用宏的代码,比如
#define CONTAINS(Class, Name)\
private:\
std::list<Class> m_##Name##s;\
public:\
void add_##Name(const Class& a_##Name) {\
m_##Name##s.push_back(a_##Name);\
}\
int get_##Name(int pos) {\
return m_##Name##s.at(pos);\
}\
// ... more member functions
稍后你可以声明一个类
class my_class {
CONTAINS(int, integer)
// ...
};
写
my_class a(...);
a.add_integer(10);
我对这种粘贴在宏中的风格感到困惑,因为我缺少具体的反驳论点。但除此之外,我接受以下优点
- 您可以轻松地为您的类添加任意类型的列表接口(interface)
- 避免频繁重复代码
- 你有一个易于使用的界面(比如
add_integer(10)
)
现在我正在寻找满足上述所有这些要点并避免这种旧的 C 宏样式的替代方案。我的第一个想法是创建一个抽象基类模板
template<typename T>
class list_interface {
private:
std::list<T> m_list;
public:
void add_element(const T& x) {
m_list.push_back(x);
}
// ... more member functions
};
并像这样通过继承将它添加到我的类中
class my_class : public list_interface<int> {
// ...
};
现在我也可以写了
my_class a;
a.add_element(10);
但我担心以下几点:
- 你只能将一个列表添加到你的类(class)
- 你公开继承了一个没有虚析构函数的类
- 我不符合专家的第三点(
add_element(10)
而不是add_integer(10)
)
我的问题是:
- 旧的 C 宏结构的缺点是什么
- 如何在没有宏的情况下提供类似的功能
最佳答案
怎么样:
#include <vector>
template<typename T>
class Plop
{
std::vector<T> data;
public:
void add(T const& v) {data.push_back(v);}
T get(int pos) {return data.at(pos);} // at() is not valid on lists.
};
class my_class
{
public:
Plop<int> integer;
Plop<float> floater;
};
int main()
{
my_class x;
x.integer.add(5); // similar to x.add_integer(5);
x.integer.get(0); // similar to x.get_integer(0);
}
它满足所有要求:
- 您可以轻松地为您的类添加任意类型的列表接口(interface)
- 避免频繁重复代码
- 你有一个易于使用的界面(比如 add_integer(10))
我的问题是:
旧的 C 宏结构的缺点是什么
- 恶心因素。
- 调试。
- 可以将单个列表传递给其他函数或方法。
如何在没有宏的情况下提供类似的功能
- 见上文。
关于c++ - 此宏结构的缺点和可能的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1686423/