Ошибка в перегрузке оператора * - PullRequest
0 голосов
/ 02 сентября 2011

У меня небольшая проблема с перегрузкой оператора.У меня есть класс с именем AtmospheridData, в котором я определяю оператор *.

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

//! Operator * (scalar)
AtmosphericData operator*(const qreal& qrMult) const;

и определение в .cpp.file, выглядит следующим образом:

AtmosphericData AtmosphericData::operator*(const qreal& qrMult) const
{
    AtmosphericData xResult;

    xResult.m_qrTemperature        = this->m_qrTemperature * qrMult;
    xResult.m_qrPressure           = this->m_qrPressure * qrMult;
    xResult.m_qrDensity            = this->m_qrDensity * qrMult;
    xResult.m_qrAbsoluteHumidity   = this->m_qrAbsoluteHumidity * qrMult;
    xResult.m_qrVisibility         = this->m_qrVisibility * qrMult;
    xResult.m_qrPrecipitationIndex = this->m_qrPrecipitationIndex * qrMult;
    xResult.m_xWind.qrNS           = this->m_xWind.qrNS * qrMult;
    xResult.m_xWind.qrEW           = this->m_xWind.qrEW * qrMult;
    xResult.m_xWind.qrVert         = this->m_xWind.qrVert * qrMult;

     xResult.m_xPrecipitationType = this->m_xPrecipitationType;

     return xResult;
}

Затем я использую класс в следующем выражении:

AtmosphericData c2;
AtmosphericData t1;
AtmosphericData t2;
AtmosphericData y0;
AtmosphericData y1;
qreal           hx;

/* other code */

c2 = - (3 * (y0 - y1) + (hx * ((2 * t1) + t2))) / (hx * hx);

Когда я компилирую (используя qmake-gcc под linux), я получаю следующееошибка

error: no match for ‘operator*’ in ‘3 * AtmosphericData::operator-(const AtmosphericData&) const(((const AtmosphericData&)((const AtmosphericData*)(& y1))))’

Мне кажется, что я делаю что-то не так с объявлением оператора *, но я не понимаю, что я делаю неправильно.

Может кто-нибудь сказать мне, как я могуисправить эту ошибку?

Спасибо за ваши ответы.

Ответы [ 5 ]

4 голосов
/ 02 сентября 2011

Арифметические операторы в C ++ не являются автоматически коммутативными, поэтому ваш оператор срабатывает только тогда, когда вы делаете AtmosphericData * qreal, но не тогда, когда упорядочение типов противоположно (что и происходит в выражении 3 * (y0 - y1)).

Вы также должны написать operator* для обработки регистра qreal * AtmosphericData, который должен быть записан как свободная функция, потому что тип левого операнда не соответствует типу вашего класса.

inline AtmosphericData operator*(const qreal& lhs, const AtmosphericData & rhs)
{
    // Just forward to the other operator (this works because I swapped the operands)
    return rhs * lhs;
}

Кстати, ИМХО для реализации математических операторов вы должны следовать обычной схеме реализации сначала присваивающих версий (*=), а затем вызывать их из «нормальной» (*) версии;см. FAQ по перегрузке оператора для получения более подробной информации.

0 голосов
/ 02 сентября 2011

Если вы объявите оператор внутри класса, он будет работать, только если вы используете свой класс на left .Чтобы использовать свой класс справа, вам также необходимо перегрузить оператор как бесплатную функцию:

AtmosphericData operator*(const qreal& qrMult, const AtmosphericData& data);

Вы также можете использовать Boost.Operators и получить все это бесплатно с помощью operator*=.

class AtmosphericData : boost::multipliable<AtmosphericData, qreal> 
{

   // blah

public:
    AtmosphericData& operator*=(const qreal& qrMult) {
        // blah blah
        return *this;
    }
    // by inheriting from boost::multipliable, this gives you both operator* for free
}
0 голосов
/ 02 сентября 2011

Вы определили operator *, первый аргумент которого - AtmosphericData, а второй - число. Но НЕ наоборот.

Вы должны определить и другого оператора (не являющегося членом)

AtmosphericData operator * (qreal num, const AtmosphericData& ad )
{
    return ad*num;
}
0 голосов
/ 02 сентября 2011

Вы пытаетесь умножить AtmostphereicData на int (3*blah и 2*blah), операцию, которую вы, похоже, не определили.

D Определяет оператора, который принимает левую часть от int и правую часть AtmosphereicData.

0 голосов
/ 02 сентября 2011

Если вы напишите:

c2 = - ((y0 - y1) * 3 + (hx * ((t1 * 2 ) + t2))) / (hx * hx);

вместо

c2 = - (3 * (y0 - y1) + (hx * ((2 * t1) + t2))) / (hx * hx);

тогда должно работать. Поскольку определение operator* в вашем коде требует, чтобы объект типа AtmosphericData был слева от *. То есть 3 * y не будет работать, но y*3 будет работать, когда y является объектом типа AtmosphericData.

Если вы хотите, чтобы 3*y также работал, тогда определите функцию , не являющуюся членом , как:

AtmosphericData operator*(const qreal &r, const AtmosphericData& a)
{
   return d*r;//call the other overloaded, or calculate the value here if you wish!
}

Я бы предложил вам определить другую функцию как функцию, не являющуюся членом. А если вам нужен доступ к закрытым или защищенным пользователям, сделайте это friend. В противном случае, не являющийся членом, не являющийся другом, должен быть вашим первым выбором.

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