创建宏为任何 class c++ 生成 getter

Create macro to generate getters for any class c++

最近我开始考虑如何通过名称的通用化 class/function 来通用化对私有数据成员的访问。原因是我有很多私有成员,为每个成员创建一个 getter 很麻烦。我尝试使用预处理器宏来执行以下操作

#define RETURNS(...) -> decltype((__VA_ARGS__))  { return (__VA_ARGS__); }
#define GET(classname, name, funcname) auto funcname() RETURNS(classname->name);

class foo {
private: 
    int a = 1;
    std::vector<int> b = std::vector<int>(3, 1);
    std::string c = "pika-chuuu";
public:
    foo() = default;
    ~foo() = default;

    GET(this, a, getter);
};

int main(const int argc, char* argv[]) {

    foo obj;
    std::cout << obj.getter();
    return 0;
}

这个可以编译,但是有没有一种方法可以在 foo 中创建一个 getter,它采用 运行 时间和 returns 的变量名称] this->(name)?使用这种方法,我可以减少引入 getters 的代码,但是数据成员越多,我需要的 getters 就越多,但我希望有一个可以访问任何数据成员按名字。您对如何完成有任何建议吗? 我正在寻找这样的语法:

#define RETURNS(...) -> decltype((__VA_ARGS__))  { return (__VA_ARGS__); }
#define GET(classname, name) RETURNS(classname->name);
class foo {
private: 
    int a = 1;
    std::vector<int> b = std::vector<int>(3, 1);
    std::string c = "pika-chuuu";
public:
    foo() = default;
    ~foo() = default;

    auto getter(auto x) GET(this, x);
};

这里x是我输入的名字,ab或者c

Do you have any suggestion of how can it be done?

为什么所有 decltype-> 以及带有 __VA_ARGS__RETURNS 的可变参数宏...只是:

#include <vector>
#include <string>

#define DECL_GETTER(name) \
        auto get_##name() { return this->name; }

class foo {
private: 
    int a = 1;
    std::vector<int> b = std::vector<int>(3, 1);
    std::string c = "pika-chuuu";
public:
    DECL_GETTER(a)
    DECL_GETTER(b)
    DECL_GETTER(c)
};

int main() {
    foo f;
    f.get_a();
    f.get_b();
    f.get_c();
}

我还会添加 const 重载。

你可能想研究一下QT properties system,那基本上就像是这个的更高级版本。

主观:TBH 使用这样一个宏,你在不需要它们的地方进行抽象。值得花时间吗?它用 non-obvious 宏隐藏了一些明显的代码,使 IDE 更难“跳转到定义”,使维护和推理更难。重命名具有 IDE 特征的变量会更难。考虑逐字逐句地手工编写这些 getter - 考虑第一眼看上去显而易见的可读且清晰的代码,即使您不得不牺牲一点重复并键入更多 () { return 个字符。配置你的IDE,这样你就可以“为这个成员函数创建一个getter/setter”动作来加速你的开发(例如QT Creator,这是一个非常好的功能)。

is there a way I can create a getter in foo, which takes the name of a variable at run-time and returns this->(name)?

C++ 是一种没有 reflection 的语言,所以基本上不需要,否则它需要的样板代码远远超过它的价值。

修订:

@HolyBlackCat所述,不需要堆分配,你应该直接使用impl class作为对象:

class foo{
    struct foo_data
    {
        int i;
        std::string s;
    };
    foo_data data;
public:
    template<typename ... Args>
    foo(Args&& ... args)
    : data(std::forward<Args>(args)...)
    {}

    foo_data const* operator->() const   // Returns a pointer to const data
    {
        return &data;
    }
};

然后访问数据:

int main()
{
    auto f = foo(3, "hello");
    std::cout << f->i << f->s;          // Accessing data, prints: "3hello"
    // f->i += 1;                       // Error: assignment of member in read-only object
}