Проблема с классификатором типов C++

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

проблема заключается в моем классе фракций. Теперь моя задача-перегрузить оператор plus, чтобы сложить две дроби.

фракции.cpp:

#include "Fraction.h"

const Fraction Fraction::operator+ (const Fraction &rhs) const
{
    return Fraction(_num * rhs.GetDen() + (rhs.GetNum() * _den), _den * rhs.GetDen());
}

фракции.h

#pragma once

class Fraction
{
    public:
        Fraction(const int &num, const int &den) : _num(num), _den(den) {}
        ~Fraction(void) {}
        const int GetNum(void) { return _num; }
        const int GetDen(void) { return _den; }
        const Fraction operator+ (const Fraction &rhs) const;

    private:
        const int _num, _den;
};

Visual Studio жалуется, что мои методы доступа к фракциям не могут " преобразовать этот указатель из фракции const в фракция.'& Я совершенно сбит с толку.

5 ответов


вам нужно квалифицировать ваши аксессоры как const тоже:

int GetNum(void) const { return _num; }

кстати, квалификация возвращаемого типа как const int на самом деле не имеет смысла, это будет int в любом случае. Компилятор должен выдать предупреждение.


методы доступа GetNum и GetDen не объявляются как "const", поэтому их нельзя вызывать в операторе+ против фракций const.


первый вопрос, почему у вас есть функция, возвращающая "фракцию const" в первую очередь? Это накладывает произвольное ограничение на то, как можно использовать ваш код. Совершенно ясно, что ваш класс фракций уже по большому счету неявно const. В этом нет необходимости.

однако ваши функции-члены не являются const. То есть, они не говорят компилятору, что вы не будете пытаться изменить состояние внутри самого класса. Пожалуйста, поместите ключевое слово "const" в конце объявления функций-членов для всех функций-членов, которые не изменяют состояние.


ваши геттеры не const:

    int GetNum() const { return _num; }
    int GetDen() const { return _den; }
         ///    ^^^^^^^^

на самом деле вам не нужны эти геттеры. Лично я бы их выбросил.
Примечание: что класс является другом самого себя и, таким образом, может получить доступ к членам другого экземпляра.

const Fraction Fraction::operator+ (const Fraction &rhs) const
{
    return Fraction(_num * rhs._den+ (rhs._num * _den), _den * rhs._den);
}

Другие Примечания:

  • также установка void в качестве параметра не является хорошей идеей (это стиль C).
  • const int действительно не имеет значения, просто верните int.
  • пожалуйста, не используйте подчеркивания как первый персонаж. Его законно, но если вы не осторожны и не знаете всех правил подчеркивания, легко споткнуться.

const int GetDen(void) { return _den; }

должен (или может) быть

int GetDen(void) const { return _den; }

первый возвращает копию const. Возврат копией означает, что копия будет сгенерирована и предоставлена вызывающей функции как временный объект, поэтому объект const ("только для чтения"). Таким образом, возврат копией делает копию доступной только для чтения.

второй делает вашу функцию вызываемой, даже если объект Fraction является const - это "доступная только для чтения" функция (вы могли бы сказать). Возможно, это то, чего ты хотела. пишите, а если нет, то лучше, чем без Конста.

кстати, void в параметрах не полезен в C++, вы можете избежать его ввода и просто сказать int GetNum() const{ return _num; }

еще одна деталь: имена, начинающиеся с символа подчеркивания, зарезервированы стандартом для стандартных реализаций. Использовать их не очень опасно, но кто знает. Если вы хотите сохранить их, по крайней мере инкапсулируйте весь свой код в пространстве имен.