【问题标题】:C++ Operator>> Overloading with Mutator?C++ 运算符>> 用 Mutator 重载?
【发布时间】:2017-03-11 21:39:42
【问题描述】:

我正在尝试找出一种方法(如果可能的话)来重载 >> 运算符以使用 mutator 正确运行。比如我想写:

myClass obj;
cin >> obj.setValue;

并让它在一行中使用可用的 mutator 正确设置 obj 的私有值。我知道我可以使用一个临时变量来存储 cin 并用它设置 obj 值,但我想知道是否有更简洁的方法,比如这个。我是新手程序员,所以这是我在 myClass 中的徒劳尝试:

friend std::istream &operator>>(std::istream &in, void (myClass::*pt)(double newValue)) {
    double temp;
    in >> temp;
    pt(temp);
    return in;
}

我知道我可以简单地重载整个 myClass 来接受:

cin >> myClass;

但这会阻止我在不同时间在 myClass 中设置不同的个人值。

谢谢

【问题讨论】:

  • 欢迎来到 Stack Overflow。请花时间阅读The Tour 并参考Help Center 中的材料,您可以在这里问什么以及如何问。
  • cin >> obj.setValue; 无法工作 - 它根本不是有效的 C++ 语法(假设 setValuemyClass 的成员函数)

标签: c++ c++11 operator-overloading member-function-pointers mutators


【解决方案1】:

cin >> obj.setValuecin >> &obj.setValue无效 C++ 的示例。无法获取到 class 特定实例的成员函数的引用/指针。

您可以做的是将this 指针和指向成员函数的指针 封装在一个小的struct 中,然后在其上重载operator>>

template <typename T, typename Arg>
struct setter_t
{
    T* _this;
    void (T::*_ptr)(Arg);
};

template <typename T, typename Arg>
auto setter(T& x, void (T::*ptr)(Arg))
{
    return setter_t<T, Arg>{&x, ptr};
}

template <typename T, typename Arg>
std::istream &operator>>(std::istream &in, setter_t<T, Arg> s) 
{
    Arg temp;
    in >> temp;
    (s._this->*s._ptr)(temp);
    return in;
}

用法:

myClass obj;
std::cin >> setter(obj, &myClass::setValue);

live wandbox example


这是一个 C++17 解决方案,它不会在 setter_t 中不必要地存储 _ptr。用法:

std::cin >> setter<&myClass::setValue>(obj);

live wandbox example

【讨论】:

    【解决方案2】:

    您可以让 .setValue() 返回对 Functor 的非 const 引用(一个覆盖 operator() 的类),然后让该 Functor 覆盖

    std::istream &operator>>(std::istream &is, MySetterFunctor &x){
        double temp;
        is >> temp;
        x(temp);
        return is;
    }
    

    仿函数将由 obj 初始化,接收指向 obj 的指针并在其中使用实际 obj 的 setter 方法 void operator()(double v){ obj->set_value(v);}

    对于那些额外的黑客,你可以让 setValue 成为一个非常量的公共成员,这样你就可以像 std::cin >> obj.setValue 一样调用它,通常也可以使用 x.setValue(someDouble)。您可以将 obj.set_value 设为受保护的成员函数,并将 MySetterFunctor 设为 obj 的友元类。

    class Obj{
        public:
            friend class MySetterFunctor;
            MySetterFunctor setValue;
        ...
    }
    

    大免责声明:这都是理论上的谈话,我不确定有人愿意这样做,但我相信它会让你做你想做的事。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-19
      • 1970-01-01
      • 2016-04-08
      • 2012-06-02
      • 2014-01-14
      • 2013-03-23
      • 2013-12-03
      相关资源
      最近更新 更多