Const引用字段作为C++类中的readonly属性

Ang*_*ros 16 c++ oop properties reference design-principles

在C++类中使用const引用字段作为只读getter是否合适?

我的意思是,这段代码是否符合良好做法?

class check{
private:
    int _x;
public:
    const int& x = _x;
    void setX(int v){
        _x = v;
    }
};
Run Code Online (Sandbox Code Playgroud)

它非常像C#属性,恕我直言,并且在类使用代码中非常简单和干净:

  check s;
  int i;
  std::cin >> i;
  s.setX(i);
  std::cout << s.x << '\n';
  s.setX(7);
  // s.x = i; // Error
  std::cout<<s.x<<'\n';
Run Code Online (Sandbox Code Playgroud)

gsa*_*ras 19

这段代码符合良好做法吗?

不是真的,因为它引入了不必要的复杂性和空间开销.

此外,无论访问的值如何,您都无法执行运行时检查和/或断言.

此外,生命周期和语义会发生什么?

尝试将check代码中的一个分配给另一个,看看会发生什么.分配不正确,因为该类是不可分配的.您应该提供一个复制和移动构造函数来处理引用,这样它就不会引用旧对象的数据成员.

更好地_x直接使用并具有直接的内联吸气功能.


PS:原生C++中的C#属性?


Bia*_*sta 6

一般来说,这不是一个好习惯.

imho,在课堂使用代码中非常简单和干净.

为什么要更清楚,更容易?

  • 你引入了另一个变量成员(无用的开销).(通常,引用将作为附加成员指针实现).
  • 它使代码更难维护.您实际上是在变量成员之间创建依赖关系.
  • 它在赋值和复制操作中产生问题.如何复制操作?

"经典"的方法听起来更清晰,例如:

class Foo {
 public:
  void set_num(int value) noexcept { m_num = value; }
  int get_num() const noexcept { return m_num; }
  void set_string(std::string value) noexcept {
      m_str = std::move(value);
  }
  const std::string& get_string() const noexcept {
      return m_str;
  }
 private:
  int m_num;
  std::string m_str;
};
Run Code Online (Sandbox Code Playgroud)

从性能的角度来看,这种方法应该是首选.

  • 时序复杂性:调用get_variable上的内联函数比你的"参考方法"不引入更多的开销.此外,它可以被编译器高度优化(因为代码简单).
  • 空间复杂性:它不会引入额外的数据成员.