класс фракций c ++. операторы перегрузки?

Я делаю дробный класс для школьного проекта, и у меня ломается мозг. Мне сказали перегрузить операторы ‹< и >> с помощью ключевого слова friend. Но я получаю ошибки из-за этого.

Я разместил соответствующий код здесь: http://pastebin.com/NgCABGJ2

К этим ошибкам относятся: ошибка C2270: '‹<': модификаторы не разрешены для функций, не являющихся членами (эта ошибка относится ко всем тем, которые объявлены как друзья)

Это было в определении оператора ‹. ошибка C2333: 'Fraction :: operator ‹': ошибка в объявлении функции; пропуска тела функции

Всего 46 ... это кошмар.

РЕДАКТИРОВАТЬ:

Спасибо, я решил почти все ошибки, но осталось еще 3

ошибка C2664: 'Fraction :: Fraction (const Fraction &)': невозможно преобразовать параметр 1 из 'int' в 'const Fraction &'. Происходит в этом операторе:

Fraction<int> test1, test2, test3(10);

ошибка C2248: «Fraction :: operator ==»: невозможно получить доступ к закрытому члену, объявленному в классе «Fraction». Ошибка C2248: «Fraction :: operator‹ »: невозможно получить доступ к закрытому члену, объявленному в классе« Fraction »

Я не понимаю этих двух, но это происходит в следующих утверждениях:

    if (test1 == test2)
    cout << "\nTest1 is equal to Test2";
if (test1 < test2)
    cout << "\nTest1 is less than Test2";

Спасибо!

‹>‹> ‹>> РЕДАКТИРОВАТЬ 2‹ ›>‹> ‹>

Я исправил другие ошибки частного доступа, но теперь у меня есть несколько действительно странных ошибок:

Полный код: http://pastebin.com/MVrB67SR

Ошибки:

Ошибка 1, ошибка LNK2001: неразрешенный внешний символ «class Fraction __cdecl operator- (class Fraction const &, class Fraction const &)» (?? G @ YA? AV? $ Fraction @ H @@ ABV0 @ 0 @ Z) Ошибка 2 error LNK2001: неразрешенный внешний символ «класс Fraction __cdecl operator + (class Fraction const &, class Fraction const &)» (?? H @ YA? AV? $ Fraction @ H @@ ABV0 @ 0 @ Z) Ошибка 3 Ошибка LNK2001: неразрешенный внешний символ "класс Fraction __cdecl operator / (class Fraction const &, class Fraction const &)" (?? K @ YA? AV? $ Fraction @ H @@ ABV0 @ 0 @ Z) c: \ Users \ caleb jares \ documents \ Visual Studio 2010 \ Projects \ Solution11-5 \ Solution11-5 \ Solution11-5.obj Ошибка 4, ошибка LNK2001: неразрешенный внешний символ «оператор класса Fraction __cdecl * (класс Fraction const &, класс Fraction const &)» (?? D @ YA? AV? $ Fraction @ H @@ ABV0 @ 0 @ Z) Ошибка 5, ошибка LNK2001: неразрешенный внешний символ "class std :: basic_ostream> & __cdecl operator ‹< (class std :: basic_ostream> const &, class Fraction)" (?? 6 @ YAAAV? $ Basic_ostream @ DU? $ Char_traits @ D @ std @@@ std @@ ABV01 @V? $ Fraction @ H @@@ Z) Ошибка 6, ошибка LNK2001: неразрешенный внешний символ "class std :: basic_istream> & __cdecl operator >> (class std :: basic_istream> const &, class Fraction)" (?? 5 @YAAAV? $ Basic_istream @ DU? $ Char_traits @ D @ std @@@ std @@ ABV01 @ V? $ Fraction @ H @@@ Z) Ошибка 7, ошибка LNK1120: 6 неразрешенных внешних элементов

Еще раз спасибо за помощь!


person Caleb Jares    schedule 07.10.2010    source источник
comment
Мне как бы не нравится, что вы помещаете код в pastebin, но, по крайней мере, срок его действия - «никогда», поэтому ссылка всегда должна оставаться действительной.   -  person Omnifarious    schedule 07.10.2010
comment
Я не думал, что было бы хорошо задавать этот вопрос. Всегда ли мне вставлять код сюда?   -  person Caleb Jares    schedule 07.10.2010
comment
Вы можете опубликовать сокращенный фрагмент кода, то есть репрезентативный код, вызывающий ошибки компилятора.   -  person In silico    schedule 07.10.2010


Ответы (5)


Похоже, вы пытались объявить friend ostream &operator<<(…) const;. В friends важно то, что они не являются участниками. Функция friend существует вне области действия класса, даже если она определена внутри блока class {}. Другими словами, вы объявляете функцию ::operator<<(), а не fraction::operator<<(). И только функции-члены могут иметь этот завершающий const, поскольку он изменяет тип this.

Факт в том, что operator<< для вывода обычно в любом случае не должен быть другом. Он просто получает значение и пересылает его в поток… для этого не требуется специального разрешения! То же самое относится к operator<.

Полностью выведите функции за пределы блока класса. Ваш TA не может жаловаться на ваш дизайн, используя friend реже.

person Potatoswatter    schedule 07.10.2010
comment
Спасибо! в этом столько смысла! И вы говорите, что я должен определять операторы вне тела? Я не знал, что это возможно. Должен ли я сделать объявление (например, bool thisfunction ();) и определить (реализовать его - bool thisfunction () {...}) снаружи? Извините, я не знаю словаря для этого. - person Caleb Jares; 07.10.2010
comment
@cable: Да, совершенно верно. Как я уже сказал, определение функции friend внутри class{} - то же самое, что определение ее вне class{}, так что вы уже почти у цели. Просто скопируйте и вставьте. О, есть одно отличие - вы должны уточнять имена статических членов и вложенных типов. Но у вас их нет, как и не должно: v). - person Potatoswatter; 07.10.2010

Просто уберите константу ... они не функции-члены, поэтому они не могут быть константами. Вы также должны передать объект класса по ссылке ... нет смысла делать копии все время.

person Tony Delroy    schedule 07.10.2010
comment
Спасибо за ответ. может ты сможешь объяснить, почему они не могут быть константными? - person Caleb Jares; 07.10.2010
comment
@ cable729: Если функция-член объявлена ​​const, это означает, что она не изменяет объект, для которого вызывается (объект this указывает на внутреннюю часть функции). Для функции, не являющейся членом, такого объекта нет (нет this), поэтому нет ничего, что могло бы быть константой. - person sth; 07.10.2010

Я не могу определить первую из ваших новых ошибок, но ошибки operator== и operator< вызваны тем, что по умолчанию они private внутри вашего класса. Перед ними нужна public: строка, чтобы они были доступны для внешнего мира.

person Mark B    schedule 07.10.2010

Модификаторы, на которые он ссылается, - это константа в конце функции после параметров:

friend ostream& operator<<(const ostream& output, const Fraction<T> value) const; //<-- that
friend istream& operator>>(const istream& input, Fraction<T> value) const; // <-- and that

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

person Benjamin Lindley    schedule 07.10.2010

Ключевое слово const после объявления функции разрешено только для функций-членов:

// This is not a member function!
template <class T>
ostream& operator<<(const ostream& output,
                    const Fraction<T>& value) /* No const! */
{
    // ...
}

Это недопустимо, потому что const в конце объявления функции-члена означает, что эта функция-член не будет изменять значения объекта *this, отличные от mutable. Поскольку это функция, не являющаяся членом, const, примененный к концу объявления функции, является ошибкой.

Кроме того, если вы определяете оператор < (или другие операторы, такие как >, +, - и т. Д.) Как член класса, он может принимать только один параметр:

// Only accepts a single parameter (the "right-hand-side" argument)
bool operator<(Fraction<T> const& right) const
{
    // ...
}

Хотя, как указал Potatoswatter, вы должны определять такие операторы вне класса как бесплатные функции.

person In silico    schedule 07.10.2010
comment
Определения членов operator могут привести к неожиданному взаимодействию с полиморфизмом и семантикой вызова функций. По привычке бесплатные функции лучше. - person Potatoswatter; 07.10.2010