как перегрузить оператор присваивания переменной класса - PullRequest
0 голосов
/ 26 февраля 2020

Я пытаюсь отследить значение переменной, которую я введу в функцию 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;
}

Ответы [ 2 ]

0 голосов
/ 26 февраля 2020

Вы можете перегрузить присвоение только для класса. Но вы можете сделать эту переменную типом класса с перегруженным присваиванием, например:

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 ++) даже перегрузить оператор &, но если функция API не является шаблоном, она должна вернуть указатель. Наблюдение за доступом через него очень зависит от среды c.

Во время отладки вы обычно можете установить точку наблюдения памяти, которая будет приостанавливать выполнение программы при записи или даже при чтении из определенной области памяти ( для GDB см. Настройка точек наблюдения ; VS должен иметь аналогичную функцию). Для этого требуется аппаратная поддержка (или безумно медленный интерпретатор-отладчик), поэтому общее количество точек наблюдения часто очень ограничено.

Без отладчика вы можете создать часы с одним выстрелом, используя Трюки защиты памяти (например, защита страницы, содержащей переменную, и снятие защиты с нее при первом SEGV), но это слишком просто для agile для обычного использования.

0 голосов
/ 26 февраля 2020

Чтобы отслеживать изменения в переменной, вам необходимо назначить класс, а не содержащуюся переменную.

Сначала избавьтесь от val. Имейте только личное значение m_value. Таким образом, все обращения должны go через ваши функции-члены, которые могут отслеживать изменения.

operator= должен возвращать ссылку на класс (return *this;), а не значение.

Назначение объекту класса:

MonitoredVariable = 10.2;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...