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

#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)
    class my_class : public list_interface<int> {
        // ...
    };
    

    现在我也可以写
    my_class a;
    a.add_element(10);
    

    但我担心以下几点:
  • 您只能将一个列表添加到您的类
  • 您从没有虚拟析构函数的类公开继承的
  • 我没有达到专业水平的第三点(用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/

    10-10 05:18