类与对象
一、运算符重载
运算符重载,就是对已有的运算符进行重新定义,赋予另一种功能,以适应不同的数据类型。
运算符重载只是一种“语法上的方便”,也就是它只是另一种函数调用的方式。 在C++中,可以定义一个处理类的新运算符。这种定义很像一个普通的函数定义,只是函数的名字由关键字operator
及其紧跟的运算符组成。差别仅此而已。它像任何其他很熟一样也是一个函数,当编译器遇到适合的模式时,就会调用这个函数。 语法:定义重载的运算符就像定义函数,只是改函数的名字是operator@
,这里的@代表了被重载函数的运算符。函数参数中参数个数取决于两个因素。运算符是一元(一个参数)的还是二元(两个参数);运算符被定义为全局函数(对于一元是一个参数,对于二元是两个参数)还是成员函数(对与一元没有参数,对于二元是一个参数,此时该类的对象用作左耳参数)
【两个极端】有些人很容易滥用运算符重载,它确实是一个有趣的工具,但是应该注意,它仅仅是一种语法上的方便而已,是另外一种函数调用的方式。从这个角度来看,只有在能使涉及类的代码更易写,尤其是读时(请记住,读代码的机会比我们写代码多多了)才有理由重载运算符。如果不是这样,就改用其他更易用、更易读的方式,对于运算符重载,另外一个常见的反应就是恐慌:突然之间,C运算符的含义变得不同寻常了,一切都变了,所有C代码的功能都要改变!并非如此,对于内置的数据类型的表达式的运算符是不可能改变的。(例如想重载int类型数据的+号)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 class Person { friend ostream& operator <<(ostream &out,Person ob); private : char *name; int age; public : Person (){ cout<<"无参构造" <<endl; } Person (char *name,int age){ cout<<"有参构造" <<endl; this ->name = new char [strlen (name)+1 ]; strcpy (this ->name,name); this ->age = age; } ~Person (){ cout<<"析构函数" <<endl; if (this ->name != NULL ){ delete [] this ->name; } } Person (const Person &ob){ cout<<"拷贝构造函数" <<endl; this ->age = ob.age; this ->name = new char [strlen (name)+1 ]; strcpy (this ->name,ob.name); } void showPerson () { cout<<"name:" <<this ->name<<",age:" <<this ->age<<endl; } }; ostream& operator <<(ostream &out,Person ob){ out<<"name:" <<ob.name<<",age:" <<ob.age<<endl; return out; } void test01 () { Person ob1 ("lucy" ,18 ) ; ob1.showPerson (); Person ob2 ("bob" ,20 ) ; cout<<ob1<<ob2<<endl; }
运行结果:
注意点:
这个函数重载函数为全局函数,要使用Person类中的私有的成员,需要将这个函数设置为Person类的友类。
要实现out<<ob1<<ob2<<endl;
后面还要连接其他的,需要返回值设置为out。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 #include <iostream> #include <cstring> using namespace std;class Person { friend ostream& operator <<(ostream &out,Person ob); friend Person operator +(Person &ob1,Person &ob2); private : char *name; int age; public : Person (){ cout<<"无参构造" <<endl; } Person (char *name,int age){ cout<<"有参构造" <<endl; this ->name = new char [strlen (name)+1 ]; strcpy (this ->name,name); this ->age = age; } ~Person (){ cout<<"析构函数" <<endl; if (this ->name != NULL ){ delete [] this ->name; } } Person (const Person &ob){ cout<<"拷贝构造函数" <<endl; this ->age = ob.age; this ->name = new char [strlen (name)+1 ]; strcpy (this ->name,ob.name); } void showPerson () { cout<<"name:" <<this ->name<<",age:" <<this ->age<<endl; } }; ostream& operator <<(ostream &out,Person ob){ out<<"name:" <<ob.name<<",age:" <<ob.age<<endl; return out; } Person operator +(Person &ob1,Person &ob2){ char *tmp_name = new char [strlen (ob1.name) + strlen (ob2.name) + 1 ]; strcpy (tmp_name,ob1.name); strcat (tmp_name,ob2.name); int tmp_age = ob1.age + ob2.age; Person ob3 = Person (tmp_name,tmp_age); return ob3; } void test01 () { Person ob1 ("lucy" ,18 ) ; ob1.showPerson (); Person ob2 ("bob" ,20 ) ; cout<<ob1<<ob2<<endl; } void test02 () { Person ob1 ("lucy" ,18 ) ; Person ob2 ("bob" ,20 ) ; Person ob3 = ob1+ob2; cout<<ob3; cout<<(ob1+ob2); Person ob4 = operator +(ob1,ob2); ob4.showPerson (); } int main (int argc, char *argv[]) { test02 (); return 0 ; }
运行结果:
注意点:
这个operator +
函数重载函数为全局函数,要使用Person类中的私有的成员,需要将这个函数设置为Person类的友类。
思考:要实现多个(超过两个)对象相加如何实现?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 #include <iostream> #include <cstring> using namespace std;class Person { friend ostream& operator <<(ostream &out,Person ob); private : char *name; int age; public : Person operator +(Person &ob){ char *tmp_name = new char [strlen (this ->name) + strlen (ob.name) + 1 ]; strcpy (tmp_name,this ->name); strcat (tmp_name,ob.name); int tmp_age = this ->age + ob.age; Person ob3 = Person (tmp_name,tmp_age); return ob3; } Person (){ cout<<"无参构造" <<endl; } Person (char *name,int age){ cout<<"有参构造" <<endl; this ->name = new char [strlen (name)+1 ]; strcpy (this ->name,name); this ->age = age; } ~Person (){ cout<<"析构函数" <<endl; if (this ->name != NULL ){ delete [] this ->name; } } Person (const Person &ob){ cout<<"拷贝构造函数" <<endl; this ->age = ob.age; this ->name = new char [strlen (name)+1 ]; strcpy (this ->name,ob.name); } void showPerson () { cout<<"name:" <<this ->name<<",age:" <<this ->age<<endl; } }; ostream& operator <<(ostream &out,Person ob){ out<<"name:" <<ob.name<<",age:" <<ob.age<<endl; return out; } void test01 () { Person ob1 ("lucy" ,18 ) ; ob1.showPerson (); Person ob2 ("bob" ,20 ) ; cout<<ob1<<ob2<<endl; } void test02 () { Person ob1 ("lucy" ,18 ) ; Person ob2 ("bob" ,20 ) ; Person ob3 = ob1.operator +(ob2); cout<<ob3; Person ob4 = ob1 + ob2; cout<<ob4; } int main (int argc, char *argv[]) { test02 (); return 0 ; }
运行结果:
注意点:
成员函数实现运算符重载其一个参数利用this指针代替了
调用方式与全局函数实现运算符重载完全一致