Перегрузка операторов ввода / вывода, почему это работает так, а не иначе?

ПРОБЛЕМА: я получаю ошибку компоновщика относительно этих двух операторов. Более конкретно здесь приведены точные сообщения об ошибках:

ПРИМЕЧАНИЕ: у меня есть «рабочее решение», если вы читаете до конца, я упоминаю об этом. Я не знаю, почему это работает именно так, а не так. Я бы предпочел, чтобы этот метод работал, потому что он выглядит чище без оператора ввода-вывода, висящего над моими объявлениями. Извините за длину. Я обрезал ненужные вещи, как другие перегруженные операторы, которые у меня были, потому что они не имеют отношения.

poly.obj : error LNK2005: "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class Poly &)" (??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@AAVPoly@@@Z) already defined in lab1.obj
1>poly.obj : error LNK2005: "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Poly const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABVPoly@@@Z) already defined in lab1.obj
1>d:\... fatal error LNK1169: one or more multiply defined symbols found

В моем файле .h (как вы увидите ниже) оба желаемых оператора объявлены друзьями, чтобы они могли получить доступ к закрытым членам. Я также использую их как функции, не являющиеся членами, и это правильное руководство по перегрузке операторов на этом сайте. Оператор >> является неполным, но это не должно иметь к этому никакого отношения. У меня есть идея, что это может быть связано с тем фактом, что в двух местах у меня есть «#include iostream», и, так как .cpp включает в себя .h, то из-за этого он вываливается? Не уверен, что это правильная догадка или нет. Вот полный файл .h:

//file poly.h

#ifndef POLY_H
#define POLY_H

#include <iostream>
using namespace std;

class Poly {

public:
Poly(int = 0, int = 0);                     //default constructor
Poly(const Poly &);                         //copy constructor
~Poly();                                    //destructor

friend ostream& operator<<(ostream& output, const Poly& thePoly);
friend istream& operator>>(istream& input, Poly& thePoly);

private:
int* polynomial;
int maxExponent;
};

istream& operator>>(istream& input, Poly& thePoly) {

return input;
}

ostream& operator<<(ostream& output, const Poly& thePoly) {
bool isZero = true;

for (int i = thePoly.maxExponent; i > 0; i--) {
if (thePoly.polynomial[i] != 0) {
if (thePoly.polynomial[i] < 0) {
output << " -";
}
else {
output << " +";
}

output << thePoly.polynomial[i];

if (i != 0) {
output << "x";
}
if (i != 1) {
output << "^";
}

output << i;
isZero = false;
}
}

if (isZero) {
output << " 0";
}

return output;
}

#endif

Вот вторичный файл, на который ссылаются в ошибках связывания:

// DO NOT change anything in this file. Your code must compile and give the
// correct output with this main on the linux machines.

// Make sure the file containing the member function source is: poly.cpp
// Use all lowercase in the file names.

// This main does not do a thorough job of testing.  When testing arrays,
// be sure to test the middle and also all the boundary conditions.  Test
// values on the boundary and outside the boundaries, i.e., too big/small.

#include "poly.h"#include <iostream>
using namespace std;

int main() {
Poly A(5, 7), B(3, 4), C(2), D(A), X, Y;
Poly A2, B2, Z1, Z2;

// set polynomials A and B to desired values
// A = +5x^7 -4x^3 +10x -2
// B = +3x^4 +1x^3
cout << "Enter terms for polynomial A.  Enter a coefficient " << endl
<< "then exponent for each term. Enter -1 -1 to terminate." << endl;
cin >> A;                                     // or use a bunch of setCoeff
cout << "Enter terms for polynomial B.  Enter a coefficient " << endl
<< "then exponent for each term. Enter -1 -1 to terminate." << endl;
cin >> B;                                     // or use a bunch of setCoeff

// outputs exactly what is in quotes: "A = +5x^7 -4x^3 +10x -2"cout << "A =" << A << endl;
// outputs exactly what is in quotes: "B = +3x^4 +1x^3"cout << "B =" << B << endl << endl;

return 0;
}

Странно (по крайней мере для меня) то, что если я воздерживаюсь от объявлений и перемещаю все функции над публичными объявлениями, но все еще внутри класса, тогда программа компилируется должным образом. ПОЧЕМУ ЭТО ??? … конечно, я не был Я могу проверить, правильно ли этот компилятор означает, что он работает должным образом, потому что мне нужно завершить оператор >>, чтобы я мог вводить данные и затем выводить их.

Вот что я имею в виду под вышеуказанным изменением:

#ifndef POLY_H
#define POLY_H

#include <iostream>
using namespace std;

class Poly {

friend istream& operator>>(istream& input, Poly& thePoly) {

return input;
}

friend ostream& operator<<(ostream& output, const Poly& thePoly) {
bool isZero = true;

for (int i = thePoly.maxExponent; i > 0; i--) {
if (thePoly.polynomial[i] != 0) {
if (thePoly.polynomial[i] < 0) {
output << " -";
}
else {
output << " +";
}

output << thePoly.polynomial[i];

if (i != 0) {
output << "x";
}
if (i != 1) {
output << "^";
}

output << i;
isZero = false;
}
}

if (isZero) {
output << " 0";
}

return output;
}

public:
Poly(int = 0, int = 0);                     //default constructor
Poly(const Poly &);                         //copy constructor
~Poly();                                    //destructor

private:
int* polynomial;
int maxExponent;
};#endif

0

Решение

(уход от комментариев)

Если вы пишете тело свободной функции (как ваш оператор<<) в заголовке вы должны пометить его как встроенный, в противном случае вы нарушаете ODR, с результатами, которые вы видите (как правило, ошибки компоновщика).

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector