#include<iostream.h>
using namespace std;
// declare but not define
class test_operator;
ostream& operator<<( ostream &out, const test_operator &t );
test_operator operator+( const test_operator &left, const test_operator &right );
// definition
class test_operator
{
private:
int a;
int b;
friend ostream& operator<<( ostream &out, const test_operator &t );
friend test_operator operator+( const test_operator &left, const test_operator &right );
public:
~test_operator()
{
cout << "in default destructor" << endl;
}
test_operator() : a( 0 ), b( 0 )
{
cout << "in default constructor" << endl;
}
test_operator( const int x, const int y ) : a( x ), b( y )
{
cout << "in default constructor with params" << endl;
}
test_operator( const test_operator &ori ) : a( ori.a ), b( ori.b )
{
cout << "in copy constructor" << endl;
}
test_operator& operator=( const test_operator &right );
test_operator& operator+=( const test_operator &right );
test_operator& operator++();
test_operator& operator--();
test_operator operator++( int );
test_operator operator--( int );
};
ostream& operator<<( ostream &out, const test_operator &t )
{
out << "a=" << t.a << "; b=" << t.b;
return out;
}
test_operator operator+( const test_operator &left, const test_operator &right )
{
cout << "in operator +" << endl;
test_operator ret( left );
ret += right;
return ret; // return by value
}
test_operator& test_operator::operator=( const test_operator & right )
{
cout << "in operator =" << endl;
a = right.a;
b = right.b;
return *this;
}
test_operator& test_operator::operator+=( const test_operator & right )
{
cout << "in operator +=" << endl;
a += right.a;
b += right.b;
return *this;
}
test_operator& test_operator::operator++()
{
cout << "in operator prefix ++" << endl;
a += 1;
b += 1;
return *this;
}
test_operator& test_operator::operator--()
{
cout << "in operator prefix --" << endl;
a -= 1;
b -= 1;
return *this;
}
test_operator test_operator::operator++( int )
{
cout << "in operator postfix ++" << endl;
test_operator ret( *this );
++( *this );
return ret; // return by value
}
test_operator test_operator::operator--( int )
{
cout << "in operator postfix --" << endl;
test_operator ret( *this );
--( *this );
return ret; // return by value
}
class GT_cls
{
public:
GT_cls( int val = 0 ) : bound( val ) {}
bool operator() ( const string &s )
{
return s.size() >= bound;
}
private:
int bound;
};
// main function
int main( int argc, char ** argv )
{
test_operator test1;
test_operator test2( 1, 2 );
test_operator test3 = test1;
test_operator test4;
test4 = test2;
cout << "1 test1 = " << test1 << endl;
cout << "1 test2 = " << test2 << endl;
cout << "1 test3 = " << test3 << endl;
cout << "1 test4 = " << test4 << endl;
test1 = test3 + test4;
cout << "2 test1 = " << test1 << endl;
cout << "2 test3 = " << test3 << endl;
cout << "3 --test1 = " << --test1 << endl;
cout << "3 ++test3 = " << ++test3 << endl;
cout << "4 test1-- = " << test1-- << endl;
cout << "4 test3++ = " << test3++ << endl;
cout << "5 test1 = " << test1 << endl;
cout << "5 test3 = " << test3 << endl;
cout << "test3 + test4 = " << test3 + test4 << endl;
GT_cls gt_obj( 5 );
string test_str1 = "abcd";
string test_str2 = "abcdef";
cout << "result1 = " << gt_obj( test_str1 ) << "; result2 = " << gt_obj( test_str2 ) << endl;
return 0;
}
说明:
这个类是一个简单的测试操作符的重载的类,利用操作符重载,我们可以很简化一些类的操作,更能避免一些不必要的错误。
操作符可以是类的成员,也可以是类的友元,但一般取舍原理:
如果使用该操作符,会更改类本身的状态的,建议定义为成员函数;其它建议定义为友元函数;
综上,建议=、+=、++、--等定义为成员函数,<<、+等可以定义为友元函数。
特别注意:
1、io相关的操作符一般都定义为如上所示的二元操作符,返回值和第一个参数是流对象的引用,这样比较符合标准库的使用习惯,也能更好的形成调用链;
2、自增++、自减--操作符,前置不需要形参,后置需要一个无用的形参以示区别。
后置时,需要保存类当前的状态,然后对类的状态进行更改,所以我们在使用预置类型的时候,没有特别必要,也都应使用前置的自增++、自减--操作符。