【问题标题】:how to overload assignment operator on class member variable如何在类成员变量上重载赋值运算符
【发布时间】:2020-02-26 16:35:25
【问题描述】:

我正在尝试跟踪我将在 API 函数中输入的变量的值。 一种选择是重载赋值运算符并将一些代码放在那里。但是如何在类的成员变量上重载赋值运算符呢?

#include <iostream>
using namespace std;

template <class T>
class MonitoredVariable1
{

public:
    MonitoredVariable1() {  }
    MonitoredVariable1(const T& value) : m_value(value) {}

    operator T() const { return m_value; }

    T val;

    T& operator = (const T& value)
    {
        val = value;
        m_value = value;
        std::cout << "value updated" << " \n";  //THIS NEVER GET PRINTED!!!

        return val;
    }

private:
    T m_value;
};


int main()
{

    MonitoredVariable1<double> MonitoredVariable;
    MonitoredVariable.val = 10.2;

    std::cout << "main done..."  << " \n";
    return 0;
}

【问题讨论】:

    标签: c++ class operator-overloading


    【解决方案1】:

    要监控变量的变化,您需要分配给类,而不是包含的变量。

    首先,摆脱val。仅具有私有 m_value 值。这样,所有访问都必须通过可以跟踪更改的成员函数。

    operator= 应该返回对类 (return *this;) 的引用,而不是值。

    分配给类对象:

    MonitoredVariable = 10.2;
    

    【讨论】:

    • 谢谢。但是 API 函数不会接受这个作为输入。它只接受 &Monitoredvariable.val 。函数参数是 APIfunc(*double)。
    • @DonI 这是一个不同的要求:能够在不监视更改的情况下访问包含的值。您可以轻松添加成员函数来返回所需的指针。
    • @DonI 如果不使用第 3 方工具,您将无法监控更改。如果 API 需要指向 double 的指针,您将无法使用标准 C++ 监视 API 所做的更改。
    • 所以...我怎么能写一个会员功能或者这是不可能的?
    • @DonI 最简单的是T *GetValPtr() { return &amp;m_value; }。也可以编写使用const 和引用的变体。但是,使用返回的指针写入的值的任何更改都将不受监控。
    【解决方案2】:

    您只能在类上重载分配。但是您可以将该变量设为具有重载赋值的类类型,例如:

    class Monitor {
        class Monitored {
            double x;
        public:
            Monitored &operator= (double v) {
                std::cout << "Assigned " << v << std::endl;
                x = v;
                return *this; // don’t forget this!
            }
    
            operator double() const {
                std::cout << "Accessed " << x << std::endl;
                return x;
            }
        };
        Monitored val;
    };
    

    您可能需要重载更多运算符,并将对Monitor 的引用传递给val(如果内存不足,可以使用一些技巧来计算它)。

    您甚至可以(在现代 C++ 中)重载 &amp; 运算符,但除非 API 函数是模板,否则它必须返回指针。监视通过它的访问是非常特定于环境的。

    在调试期间,您通常可以设置一个内存观察点,该观察点将在写入或什至读取特定内存位置时暂停程序执行(对于 GDB,请参阅Setting Watchpoints;VS 应该具有类似的功能)。不过,这需要硬件支持(或非常慢的调试器解释器),因此观察点的总数通常非常有限。

    如果没有调试器,您也许可以使用内存保护技巧(例如保护包含变量的页面,并在第一个 SEGV 上取消保护它)进行一次性监视,但这对于正常使用来说太脆弱了。

    【讨论】:

      猜你喜欢
      • 2011-05-16
      • 2014-05-18
      • 1970-01-01
      • 2012-02-11
      • 2021-06-28
      • 2011-10-20
      • 1970-01-01
      • 1970-01-01
      • 2015-04-28
      相关资源
      最近更新 更多