关于运算符重载?
请问运算符重载是否只能是成员函数或者是类的友员?
我在一个程序中重载了<<,若加上友员就能编译通过,不加就说:
binary'<<':no operator defined wich takes a right-hand operand of type'class XX'????
问题点数:0、回复次数:11Top
1 楼telantlan(宇翔)回复于 2003-11-01 08:25:51 得分 0
给你一到程序看看:
#include <iostream>
#include <ctype.h>
#include <stdlib.h>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
class Variable {
public:
char id;
int exp;
Variable() { // required by <vector>;
}
Variable(char c, int i) {
id = c; exp = i;
}
bool operator== (const Variable& v) const {
return id == v.id && exp == v.exp;
}
bool operator< (const Variable& v) const { // used by sort();
return id < v.id;
}
};
class Term {
public:
Term() {
coeff = 0;
}
int coeff;
vector<Variable> vars;
bool operator== (const Term&) const;
bool operator!= (const Term& term) const { // required by <list>
return !(*this == term);
}
bool operator< (const Term&) const;
bool operator> (const Term& term) const { // required by <list>
return *this != term && (*this < term);
}
int min(int n, int m) const {
return (n < m) ? n : m;
}
};
class Polynomial {
public:
Polynomial() {
}
Polynomial operator+ (Polynomial&);
void error(char *s) {
cerr << s << endl; exit(1);
}
private:
list<Term> terms;
friend istream& operator>> (istream& in, Polynomial& polyn) {
char ch, sign, coeffUsed, id;
int exp;
Term term;
in >> ch;
while (true) {
coeffUsed = 0;
if (!isalnum(ch) && ch != ';' && ch != '-' && ch != '+')
polyn.error("Wrong character entered2");
sign = 1;
while (ch == '-' || ch == '+') { // first get sign(s) of Term
if (ch == '-')
sign *= -1;
ch = in.get();
if (isspace(ch))
in >> ch;
}
if (isdigit(ch)) { // and then its coefficient;
in.putback(ch);
in >> term.coeff;
ch = in.get();
term.coeff *= sign;
coeffUsed = 1;
}
else term.coeff = sign;
//int i;
for (int i = 0; isalnum(ch); i++) { // process this term:
id = ch; // get a variable name
ch = in.get();
if (isdigit(ch)) { // and an exponent (if any);
in.putback(ch);
in >> exp >> ch;
}
else exp = 1;
term.vars.push_back(Variable(id,exp));
}
polyn.terms.push_back(term); // and include it in the linked list;
term.vars.resize(0);
if (isspace(ch))
in >> ch;
if (ch == ';') // finish if a semicolon is entered;
if (coeffUsed || i > 0)
break;
else polyn.error("Term is missing"); // e.g., 2x - ; or just ';'
else if (ch != '-' && ch != '+') // e.g., 2x 4y;
polyn.error("wrong character entered");
}
for (list<Term>::iterator it = polyn.terms.begin(); it != polyn.terms.end(); it++)
if (it->vars.size() > 1)
sort(it->vars.begin(),it->vars.end());
return in;
}
friend ostream& operator<< (ostream& out, const Polynomial& polyn) {
int afterFirstTerm = 0, i;
for (list<Term>::const_iterator pol = polyn.terms.begin(); pol != polyn.terms.end(); pol++) {
out.put(' ');
if (pol->coeff < 0) // put '-' before polynomial
out.put('-'); // and between terms (if needed);
else if (afterFirstTerm) // don't put '+' in front of
out.put('+'); // polynomial;
afterFirstTerm++;
if (abs(pol->coeff) != 1) // print a coefficient
out << ' ' << abs(pol->coeff);// if it is not 1 nor -1, or
else if (pol->vars.size() == 0) // the term has only a coefficient
out << " 1";
else out.put(' ');
for (i = 1; i <= pol->vars.size(); i++) {
out << pol->vars[i-1].id; // print a variable name
if (pol->vars[i-1].exp != 1) // and an exponent, only
out << pol->vars[i-1].exp; // if it is not 1;
}
}
out << endl;
return out;
}
};
// two terms are equal if all varibles are the same and
// corresponding variables are raised to the same powers;
// the first cell of the node containing a term is excluded
// from comparison, since it stores coefficient of the term;
bool Term::operator== (const Term& term) const {
int i;
for (i = 0; i < min(vars.size(),term.vars.size()) &&
vars[i] == term.vars[i]; i++);
return i == vars.size() && vars.size() == term.vars.size();
}
bool Term::operator< (const Term& term2) const { // used by sort();
if (vars.size() == 0)
return false; // *this is just a coefficient;
else if (term2.vars.size() == 0)
return true; // term2 is just a coefficient;
for (int i = 0; i < min(vars.size(),term2.vars.size()); i++)
if (vars[i].id < term2.vars[i].id)
return true; // *this precedes term2;
else if (term2.vars[i].id < vars[i].id)
return false; // term2 precedes *this;
else if (vars[i].exp < term2.vars[i].exp)
return true; // *this precedes term2;
else if (term2.vars[i].exp < vars[i].exp)
return false; // term2 precedes *this;
return ((int)vars.size() - (int)term2.vars.size() < 0) ? true : false;
}
Polynomial Polynomial::operator+ (Polynomial& polyn2) {
Polynomial result;
list<Term>::iterator p1, p2;
bool erased;
for (p1 = terms.begin(); p1 != terms.end(); p1++) // create a new polyn
result.terms.push_back(*p1); // from copies of *this
for (p1 = polyn2.terms.begin(); p1 != polyn2.terms.end(); p1++) // and
result.terms.push_back(*p1); // polyn2;
for (p1 = result.terms.begin(); p1 != result.terms.end(); ) {
for (p2 = p1, p2++, erased = false; p2 != result.terms.end(); p2++)
if (*p1 == *p2) { // if two terms are equal (except
p1->coeff += p2->coeff; // for the coefficient), add the
result.terms.erase(p2); // two coefficients and erase
if (p1->coeff == 0) // a redundant term; if the
result.terms.erase(p1);// coefficient in retained term
erased = true; // is zero, erase the term as well;
break;
}
if (erased) // restart processing from the beginning
p1 = result.terms.begin(); // if any node was erased;
else p1++;
}
result.terms.sort();
return result;
}
void main() {
Polynomial polyn1, polyn2;
cout << "Enter two polynomials, each ended with a semicolon:\n";
cin >> polyn1 >> polyn2;
cout << "The result is:\n" << polyn1 + polyn2;
}
Top
2 楼leyt(思维机器)回复于 2003-11-01 10:28:25 得分 0
是的Top
3 楼Andy84920(你也不懂)回复于 2003-11-01 16:23:32 得分 0
操作符重载函数可以是一个普通函数,成员函数,友元函数.Top
4 楼lemon520(喷血)回复于 2003-11-01 17:11:12 得分 0
要是成员和友员之一Top
5 楼fierygnu(va_list)回复于 2003-11-01 17:33:10 得分 0
不能是普通函数。Top
6 楼kdush(迷茫过后……还是迷茫……) (love—>kula始终未变)回复于 2003-11-01 18:05:57 得分 0
小弟也是C++初学者,不过小弟在C++大学教程中看到这样的话,或许对你有帮助!
·运算符函数可以是成员函数也可以是非成员函数--(友元函数也是非成员函数吧)。
·当运算符是一个成员函数时,最左边的操作数必须是运算符类的一个类对象(或者对该类对象的引用)
·如果左边的操作数必须是一个不同的类的对象,该运算符函数必须作为一个非成员函数来实现。
重载<<运算符必须有一个类型为 ostream& 的左操作数(例如表达式cout<<classObject中的cout),因此它必须是一个非成员函数。
Top
7 楼cyh811122(人生不如意)回复于 2003-11-01 20:03:51 得分 0
<<也可以用成员函数做只不过麻烦了一些没有必要呀Top
8 楼konhon(优华)回复于 2003-11-01 20:07:43 得分 0
重载<<或>>操作符它必须是一个非成员函数.
Top
9 楼telantlan(宇翔)回复于 2003-11-04 20:30:30 得分 0
不好意思,各位,是小弟菜,把"(英文输入)打成"(全拼输入);当时看到unknow char以为不可能错,原来切换了输入法,不应该,不应该.:)Top
10 楼dot99(又来混CSDN来了)回复于 2003-11-04 20:42:15 得分 0
。。。。。。。。。。。。。。。。。。。。。。Top
11 楼houdy(致力于图像/图形领域,成为有思想的程序员)回复于 2003-11-05 12:12:44 得分 0
操作符只能有成员和友元这两种,对于有些操作符,成员函数和友元的差别不大,差别就在于参数个数的不同,但是有的操作符(比如赋值操作符)只能是成员函数。详情可以参阅<Thinking in C++>里面关于operator overload这一章,讲的很清楚。Top



