#c #operator-overloading
#c #перегрузка оператора
Вопрос:
Спасибо вам всем за ваши ответы. И спасибо за cppinsight и godbolt, не знал об этом.
Я отредактировал свой вопрос здесь, что я хочу сделать. По сути, у меня есть функция сбора SDK, которая имеет аргумент pointer float в качестве входных данных, и я хочу отслеживать этот аргумент в режиме реального времени, чтобы узнать статус сбора. Теперь я получил этот код для работы:
#include <iostream>
template <class T>
class MonitoredVariable
{
public:
MonitoredVariable() {}
// MonitoredVariable(const Tamp; value) : m_value(value) {}
operator Tamp;() { return m_value; }
//operator const Tamp;() const { return m_value; }
MonitoredVariableamp; operator = (float value)
{
printf("Variable modifiedn");
this->m_value = amp;value;
printf("%f n", *this->m_value);
return *this;
}
MonitoredVariableamp; operator * () {return *this;}
private:
T m_value;
};
void SDKfunctionIcannotChange(float *a)
{
*a = (float) 5.2;
printf("%f n", *a); // if I comment this out, x will not update?!?!
return;
}
int main()
{
MonitoredVariable<float*> x;
*x=0;
SDKfunctionIcannotChange(x);
printf("%f n", *x);
return 1;
}
Но, как ни странно, если я закомментирую эту printf
команду в SDKfunctionIcannotChange
функции, то значение x не изменится. Есть какие-нибудь идеи, почему это происходит?
Так и с printf (правильно):
Variable modified
0.000000
5.200000
5.200000
и без
Variable modified
0.000000
0.000000
Спасибо..
Комментарии:
1.
*m_value = value.m_value;
это неопределенное поведение, потому что вы никогдаm_value
не указываете на afloat
. Для хранения afloat
вам нужноfloat
где-то, а не просто указатель2.
*x
не является экземпляром вашего класса. Поначалу неявные преобразования обычно кажутся хорошей идеей, но на самом деле это не так. Добавьте немного печати в свой.3.
float*
!=float
.4. Не связано:
void main()
недопустимо C . Сделайте этоint main()
5. ps: Мой первый комментарий частично связан с тем, что я неправильно прочитал код. Тем не менее это часть проблемы, поэтому я оставляю комментарий, хотя он и не совсем корректен
Ответ №1:
Это отвечает на первоначальный вопрос перед обширным редактированием.
По сути, ваша программа эквивалентна:
int main()
{
float *x = nullptr;
float y = 5;
*x = y; // here is UB since x == nullptr
}
См. cppinsights: проблемная строка выглядит следующим *static_cast<float *>(x.operator float *amp;()) = y;
образом. Таким образом, ваш код использует не пользовательский operator=
, а оператор преобразования.
В основном проблема заключается в коде, который использует шаблон.
Я не знаю, каковы были ваши намерения, может быть, это:
#include <iostream>
template <class T>
class MonitoredVariable
{
public:
MonitoredVariable() {}
MonitoredVariable(const Tamp; value) : m_value(value) {}
operator Tamp;() { return m_value; }
operator const Tamp;() const { return m_value; }
MonitoredVariableamp; operator = (const Tamp; value)
{
printf("Variable modifiedn");
m_value = value; // here was also a problem
return *this;
}
int main()
{
MonitoredVariable<float*> x;
float y = 5;
x = amp;y;
return;
}
Комментарии:
1. Альтернативой может быть создание параметра шаблона
float
, вместоfloat*
которого упростилось бы использование. пример2. Да, это еще одна интерпретация его намерения.
Ответ №2:
*x
Выражение вызывается operator*
с аргументом of x
. Во время поиска имени найден встроенный operator*
для указателей. Учитывая, что в вашем классе MonitoredVariable
есть оператор преобразования в T
(который в вашем случае является типом указателя), вызывается этот оператор преобразования, и возвращаемый указатель, который равен null, затем разыменовывается, вызывая сбой.
То, что вы, вероятно, хотели написать, это x = y
.
Комментарии:
1. Что, если OP определил a
operator*
?2. @Lingo Тогда этот оператор был бы вызван, очевидно. Но тогда OP должен был бы также реализовать ссылочный прокси-сервер для перехвата следующего назначения. Неясно, какова цель
MonitoredVariable
класса, поэтому я не могу сказать, будет ли это рекомендуемым решением.