c++ - 此宏结构的缺点和可能的替代方案

标签 c++ interface macros class-design

我最近看到一些使用宏的代码,比如

#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);

我对这种粘贴在宏中的风格感到困惑,因为我缺少具体的反驳论点。但除此之外,我接受以下优点

  1. 您可以轻松地为您的类添加任意类型的列表接口(interface)
  2. 避免频繁重复代码
  3. 你有一个易于使用的界面(比如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);

但我担心以下几点:

  1. 你只能将一个列表添加到你的类(class)
  2. 你公开继承了一个没有虚析构函数的类
  3. 我不符合专家的第三点(add_element(10) 而不是 add_integer(10))

我的问题是:

  1. 旧的 C 宏结构的缺点是什么
  2. 如何在没有宏的情况下提供类似的功能

最佳答案

怎么样:

#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);
}

它满足所有要求:

  1. 您可以轻松地为您的类添加任意类型的列表接口(interface)
  2. 避免频繁重复代码
  3. 你有一个易于使用的界面(比如 add_integer(10))

我的问题是:

  1. 旧的 C 宏结构的缺点是什么

    • 恶心因素。
    • 调试。
    • 可以将单个列表传递给其他函数或方法。
  2. 如何在没有宏的情况下提供类似的功能

    • 见上文。

关于c++ - 此宏结构的缺点和可能的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1686423/

相关文章:

go - 如何在结构字段上使用类型开关(当字段是接口(interface)类型时)?

c++ - 嵌套模板参数和类型推导

c++ - header 中 namespace 内的运算符声明?

c++ - 两个函数变量到一个函数

c++ - 是否有等效于 #if 的可以评估模板参数?

macros - 笛卡尔积匹配

assembly - 你如何比较汇编中的变量类型?

c++ - 使用成员函数指针专门化模板类

c# - 为什么 IEnumerable<T>.ToList<T>() 返回 List<T> 而不是 IList<T>?

c# - 如何将接口(interface) obj 转换为类 obj?