重构来自/到一个数据成员的读写访问器

Refactoring read write accessors from/to one data member

本文关键字:数据成员 一个 读写 写访问 重构      更新时间:2023-10-16

我想用以下结构重构访问器:

template<class T>
class ValueTime {
public:
   // accessors for val:
   const T& get_val() const { return val; }
   template<class V> void set_val(const V& v) { val = v; }
   // other accessors for tp
private:
   T val;
   std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
};

我想使val数据成员的访问器更有用和直观,主要是从"标准/提高用户期望"的角度来看,这种结构表示"时间值":

  1. template<class V = T> V get_val() { return V(val); }
  2. T& operator*() & { return val; }
  3. const T& operator*() const & { return val; }

现在我可以这样使用访问器了(见注释):

int main() {
    ValueTime<double> vt;
    // get_val() no longer returns const ref and also
    // allows explicit cast to other types
    std::chrono::minutes period{vt.get_val<int>()}; // I had to use the more pedantic static_cast<int> with the original version
    // let's use operator*() for getting a ref.
    // I think that for a structure like a ValueTime structure,
    // it's clear that we get a ref to the stored "value"
    // and not to the stored "time_point"
    auto val = *vt; // reference now;
    val = 42;
}

getter现在更有用了吗?你在新界面中看到了什么奇怪、不安全或违反直觉的地方吗(除了不向后兼容,我不在乎)?

此外,我仍然有一个疑问,如果通过返回V(val)V{val}或仅仅val来实现get_val()更好。就像现在一样,如果V有显式构造函数,它就会工作。你对这个问题怎么看?

我个人建议您尽可能使接口具有描述性,并避免任何方便的转换为引用数据或类似内容。原因很简单,就是可用性和维护。如果您或其他人使用ValueTime(重新)访问代码,当您不记得确切的接口时,您仍然希望在不重新访问ValueTime定义的情况下理解您的代码。

成员与std(如std::vector)的不同之处在于,您已经记住了它们的定义。

相关文章: