【问题标题】:Is it possible to override the default behavior of getting a struct member in C++?是否可以覆盖在 C++ 中获取结构成员的默认行为?
【发布时间】:2020-01-09 23:58:25
【问题描述】:

类似于python中的@property标签,我试图弄清楚是否可以在不调用函数的情况下覆盖c++中getter的行为。

基本上,是否可以在 c++ 中执行以下操作:

class vector2(class):
    def __init__(self):
        self.values = [1,2]

    @property
    def x(self):
        return self.values[0]
pos = vector2()
my_var = pos.x

只写 getter 和 setter 是最好的解决方案吗?

【问题讨论】:

  • 您可以通过隐式转换来伪造它,但 IMO 不值得。有极端情况,并且可以抑制优化。最好使用惯用的 C++,也就是直接使用方法:stackoverflow.com/questions/8368512/…。 MSVC 确实 具有用于动态属性的非标准 declspec 扩展,但 g++ 不支持它。 clang 在旗帜后面支持它。
  • 特别是对于那个例子,你会重载operator[],但一般来说,这在 C++ 中是不可能的
  • C++ 的方式是 getter 和 setter。 int get_x() const { return values[0]; }void set_x(int value) { values[0] = value; }
  • 对于另一种方式的数组,重载[],这个答案非常酷 - 使用指向成员的constexpr数组并进行查找。优化非常接近内联 getter 方法的功能:stackoverflow.com/a/48464023/1863938
  • 请查看“告诉,不要问”文章。 getter 和 setter 只会浪费您的时间 - 所以只需将使用实例数据的代码放在对象中即可。

标签: c++ properties overriding getter


【解决方案1】:

简短的回答是不,你不能那样做。


对于可以作为数组访问的二维向量,我会这样做:

struct Vec2 {
  float x;
  float y;

  const float &operator[](const size_t i) const {
    static_assert(sizeof(Vec2) == 2 * sizeof(float));
    assert(i < 2);
    return (&x)[i];
  }

  float &operator[](const size_t i) {
    return const_cast<float &>(std::as_const(*this)[i]);
  }
};

所以可以直接访问成员变量,也可以使用重载的下标操作符。

Vec2 v{4, 5};
v.x += 9;
v[1] = -3;

一般来说,getter 和 setter 是显式调用的。我经常看到的命名约定是给 getter 和 setter 赋予相同的名称。

class Foo {
public:
  int member() const {
    return hidden;
  }

  void member(const int value) {
    hidden = value;
  }

private:
  int hidden;
};

这种命名约定使访问非常干净,但仍然清楚地表明正在发生函数调用。

Foo f;
f.member(5);
int five = f.member();

【讨论】:

  • return (&amp;x)[i]; 这看起来不安全。
  • @SneakyTurtle 成员的顺序是有保证的,但填充不是。有了断言,应该没问题。
  • (&amp;x)[1] 是迂腐的 UB。(x 不是数组,只能视为float[1])。
猜你喜欢
  • 2014-01-09
  • 1970-01-01
  • 2010-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多