【问题标题】:Generate set/get methods for a c++ class为 c++ 类生成 set/get 方法
【发布时间】:2011-02-28 04:57:33
【问题描述】:

是否有任何工具可以自动为类生成 set 和 get 方法。

只是我非常频繁地创建类,并希望有一个工具可以为每个类成员自动生成以下功能:

Member_Type getMemberName() const; //in header file
Member_Type getMemberName() const //in source file 
{
    return member;
}

void setMemberName(const Member_Type & val); //in header
void setMemberName(const Member_Type & val) //in source file 
{
    member = val;
}

我遇到过这样的宏,但不喜欢这个主意:

#define GETSETVAR(type, name) \
private: \
    type name; \
public: \
    const type& get##name##() const { return name; } \
    void set##name##(const type& newval) { name = newval; }

可能有人知道如何使用 MS Visual Studio 或任何其他工具来做到这一点?

【问题讨论】:

  • 如果您希望您的所有成员都可以公开修改(并且如果您这样做,您的类不提供任何抽象)为什么不将它们公开? struct 默认执行此操作。
  • 以下问题的许多答案都是相关的:stackoverflow.com/questions/2977007/…。底线:你可能认为你想要这个,但这通常是一个糟糕的主意。
  • @Narek:如果 OOP 实践要求您做一些愚蠢的事情,那么也许 OOP 不是正确的选择? OOP 是达到目的的一种手段,而不是其本身的目标。目标应该始终是好的、干净的代码。通过将代码大小增加四倍并为 everything 编写 getter/setter 是无法做到这一点的。 (除此之外,这样做通常也不是好的 OOP 实践。类应该公开对类有意义的逻辑操作。get/set 通常不是有意义的操作,它们只是修改内部的快捷方式类。
  • @Narek:一个充满getter和setter的类是OO的对立面。
  • 您要求更好的解决方案:不要那样做!根据类是什么和表示什么以及类不变量是什么来实现有意义的函数。自动生成 getter 和 setter 会暴露内部实现,违反封装。

标签: c++ class methods get set


【解决方案1】:

实际上不是工具,但您可以在 Visual Assist X 中使用 Encapsulate Method,例如,它为某些私有类成员生成 getter / setter 方法。

当然,许多与 VAX 类似的工具都有相同的方法。

此外,如果您必须为大量类执行此操作,您可以实现自己的命令行工具并为您拥有的每个源文件启动它。

【讨论】:

    【解决方案2】:

    为什么要生成这些方法?

    一般来说,更好的方法是创建一个实际使用的接口来定义对对象的操作,而不仅仅是一组单独的属性。通过创建类接口,您无需编写一堆 getter 和 setter。

    如果您确实需要为所有(甚至大部分)属性生成公共 getter 和 setter,最好将其设为结构,则不需要这样的生成。

    【讨论】:

    • 并且struct 应该在课堂上公开?
    【解决方案3】:

    如果您使用的是 Visual Studio,我的 Atomineer Pro Documentation 插件会执行此操作 - 它会立即使用您选择的命名样式为成员字段添加 getter/setter 方法。

    例如如果你有这个:

    public:
    
       ...
    
    private:
        int m_Speed;
    

    然后就可以执行命令转换成这个了

    public:
        // Access the Speed
        int GetSpeed(void) const    { return(m_Speed);  };
        void SetSpeed(int speed)    { m_Speed = speed;  };
    
        ...
    
    private:
        int m_Speed;
    

    (注意:您不必使用“m_”或“Get...” - 这只是一个示例,说明它如何处理前缀或后缀命名方案。您可以配置成员命名样式使用的(速度、_speed、mSpeed、m_speed 等)和 getter/setter 方法的命名风格(GetSpeed()、get_speed() 等)


    当应用于 C# 成员时,它会做类似的事情:

    protected int m_Speed;
    

    然后您可以执行命令将其转换为自动属性:

    protected int Speed { get; set; }
    

    ...并再次执行该命令以生成带有支持字段的属性:

    protected int Speed
    {
        get { return(m_Speed); }
        set { m_Speed = value; }
    }
    private int m_Speed;
    

    【讨论】:

      【解决方案4】:

      同意 Kotti - Visual Assist(和其他插件)提供此功能。

      实际的源代码应该有 getter/setter,因为您可能希望根据需要向 setter 添加验证和更改通知。

      为此使用宏只是...可打脸。 (愿意根据要求详细说明)。

      【讨论】:

        【解决方案5】:

        我找不到工具,所以我在 10 分钟内编写了一个 python 脚本。它并不完美,但很有帮助:

        generate_getters.py:

        #!/usr/bin/python
        import sys
        
        if len(sys.argv) < 1:
            print 'usage: > python script.py <cpp_file_name>'
        
        fileName = sys.argv[1]
        className = fileName.split('.')[-2].split("/")[-1]
        
        print 'classname:' +  className
        
        def printGetterSettersForLine(line):
            syntax = line.strip().split(';')[0]
            words = syntax.split()
            if len(words) != 2:
                return
            getter = words[0] + ' ' + className + '::get' + words[1].title() + '() { \n'
            getter = getter + '     return ' + words[1] + ';\n'
            getter = getter + '}';
            print getter
        
        with open(fileName) as f:
                lines = f.readlines()
                for line in lines:
                    printGetterSettersForLine(line)
        

        用法:> python generate_getters.py ClassName.h 生成二传手留给读者作为练习。 ;)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-06-30
          • 2013-12-26
          • 2013-07-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多