2013-03-24 5 views
0

Я пытаюсь перегрузить оператор на C++, но у меня возникают некоторые трудности. Это то, что я имею в своем классе:Перегрузка оператора в C++ «<<»

ostream & operator <<(ostream & s) 
{ 
    s << w(); 
return s; 

} 
string w() 
{ 
stringstream ss; 
string str; 
for (int i=n-1; i>=0; i--) 
{ 
    if (i==n-1) 
    { 
     ss<<tablica[i] << "x^" << i; 
    } 
    else 
    { 
     if (tablica[i]<eps && tablica[i]>-eps) ss <<"+" << +tablica[i]<< "x^" << i; 
     else if (tablica[i]<eps)ss << tablica[i]<< "x^" << i; 
     if(tablica[i]>eps) ss <<"+" << +tablica[i]<< "x^" << i; 
    } 

} 
ss >> str; 
return str; 

} 

Я пытаюсь использовать это так:

cout << p << endl; 

Ошибка: no match for 'operator<<' in 'std::cout << p Вот весь мой код программы: http://codepad.org/xBijPMCp

+0

Параметр 'operator <<' должен быть * вещью справа *. –

+1

Кстати, вы используете неправильную форму 'delete'. Это неопределенное поведение. Вы также не следуете правилу 3/5, что также приводит к неопределенному поведению. Просто используйте вектор вместо этого жалкого указателя, и вам больше не понадобится деструктор. Это уже более короткий, более чистый, более безопасный код, moreso, когда вы учитываете другие функции, которые у вас есть, но не делайте этого. – chris

+0

На самом деле, прокручивая больше, я просто понял, что это базовый класс. Он должен иметь виртуальный деструктор, хотя с вектором или чем-то, он может быть таким же простым, как '~ ClassName() = default;'. – chris

ответ

2

Перегруженный оператор вызывается одним из двух способов. Либо как функция-член, где x op y; рассматривается как x.op(y);, либо глобальный, где x op y; становится op(x,y);.

Обратите внимание, что когда оператор является функцией-членом, левым операндом должен быть тот, для которого вы перегружаете оператора. В случае вставки в поток: x << y;, левый операнд является объектом потока, поэтому для перегрузки оператора в качестве функции-члена вам придется выполнять перегрузку как член класса потока.

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

Таким образом, оператор вставки почти всегда нуждается в подписи вроде:

std::ostream &operator<<(std::ostream &os, T const &t) 

(где T это независимо от типа вы собираетесь вставить).

4

ostream & operator <<(ostream & s) следует применять в отношении к определенному классу (чтобы сделать его полезным), поэтому подпись должна быть

friend ostream & operator <<(ostream & s, const class_name &c); 
+0

Сделайте его «другом», если он определен в классе, и я думаю, что это происходит здесь. –

+0

@Drew Dormann Да, конечно, чтобы иметь возможность выводить информацию о классе, он должен иметь доступ к членам этого класса (тогда следует оценить отношение друга), иначе getters() может быть достаточно –

+0

@gongzhitaao спасибо за редактирование. Важно отметить, что при работе со сложными объектами, создание которых может быть очень трудоемкой (время/память), лучше использовать пропуск по ссылке за проход по значению. –

0

Прежде всего, вам нужно подумать о своем общем дизайне. Я думаю, вы хотите перегрузить << для работы с типом вашей переменной tablica. operator<<() является двоичным оператором: декларация должна иметь следующий вид: <<(Type t1, Type t2). (вы хотите, чтобы это был член, это будет «degenarte» только для одного параметра, потому что первый - левый, будет своего рода this). В вашем случае что-то вроде:

ostream & operator <<(ostream & s, const tablica_type &c); 

Ваш tablica является глобальной переменной и п тоже с нормально не является хорошей идеей. Вы, вероятно, захотите определить класс, удерживающий tablica и n, а для этого класса переопределите < <().

1

Перегрузка оператора - это возможность сообщить компилятору, как выполнить определенную операцию, когда соответствующий оператор используется для одной или нескольких переменных.

Например, компилятор действует по-разному относительно оператора вычитания - в зависимости от того, как используется оператор.

  • Когда он помещен слева от числового значения, такого как -48, компилятор считает число отрицательным.
  • При использовании между двумя интегральными значениями, такими как 80-712, компилятор применяет операцию вычитания.
  • При использовании между целым числом и числом с двойной точностью, например 558-9,27, компилятор вычитает левое число из числа справа; операция производит число с двойной точностью.
  • Когда символ - удваивается и помещается с одной стороны переменной, например --Variable или Variable--, значение переменной должно быть уменьшено; другими словами, значение 1 вычитается из него.

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

Смежные вопросы