第19讲几种常见的运算符重载及类型转换 教学目的与要求: 了解几种常见的运算符重载函数。 掌握类型转换函数的声明和使用。 教学内容提要: 、几种常见的运算符重载函数 2、类型转换; 教学重点:类型转换 教学难点:几种常见的运算符重载函数。 教学进度:P182~P199 教学过程:
第19讲 几种常见的运算符重载及类型转换 •教学目的与要求: 了解几种常见的运算符重载函数。 掌握类型转换函数的声明和使用。 •教学内容提要: 1、几种常见的运算符重载函数; 2、类型转换; •教学重点:类型转换。 •教学难点:几种常见的运算符重载函数。 •教学进度:P182~P199 •教学过程:
19.1几个常用运算符的重载 191.1单目运算符“++”和“-”的重载 在C+中,可以通过在运算符函数参数表中是否插入关 键字int来区分前缀和后缀这两种方式 ◆对于前缀方式++0b,可以用运算符函数重载为 ob operator ++0; ∥成员函数重载 或 operator+(X&ob);∥友元函数重载, 其中ob为类X对象的引用 ◆对于后缀方式ob++,可以用运算符函数重载为 ob. operator++(int);∥成员函数重载 或 operator++(X&ob,int);∥友元函数重载 在调用后缀方式的函数时参数int一般被传递给值0。 例191:下面是+和运算符的重载的例子:
19.1 几个常用运算符的重载 19.1.1 单目运算符“++”和“--”的重载 在C++中,可以通过在运算符函数参数表中是否插入关 键字int来区分前缀和后缀这两种方式。 ◆对于前缀方式++ob,可以用运算符函数重载为 ob.operator ++(); // 成员函数重载 或 operator ++ (X& ob); // 友元函数重载, 其中ob为类X对象的引用 ◆ 对于后缀方式ob++,可以用运算符函数重载为 ob.operator ++(int); // 成员函数重载 或 operator++(X& ob,int); // 友元函数重载 在调用后缀方式的函数时,参数int一般被传递给值0。 例19.1 :下面是++和--运算符的重载的例子:
#include class test i int tl, t 2; public: test(int, int); test operator+0;∥前缀 test operator+(int);∥/后缀 test operator-0;∥前缀 test operator-(int);∥后缀 test:: test(int a, int btI=a; t2=b; 1 test test: operator++O 由由 cout<<"++test、n"; ++t1;++t2 return *this:
#include class test { int t1,t2; public: test(int,int); test operator++(); // 前缀 test operator++(int); // 后缀 test operator--() ; // 前缀 test operator--(int) ; // 后缀 }; test::test(int a,int b){t1=a;t2=b;} test test::operator++() { cout << ″++test \n″; ++t1; ++t2; return *this; } (续)
testtest: operator++(int) {cout<<“test++n”; int tmpl=tI int tmp=t2; t1++:t2++ return test(tmpl, tmp2) testtest: operator--O {cout<<“- - testin”; -t1:--t2 return *this: test test: operator--(int) {cout<“test-Ⅶn”; int tmpl=tl; int tmp=t2 tI: --t2 return test(tmpl, tmp2);
test test::operator++(int) { cout << “test++ \n”; int tmp1=t1; int tmp2=t2; t1++;t2++; return test(tmp1,tmp2); } test test::operator--() { cout << “ —test \n”; --t1;--t2; return *this; } test test::operator--(int) { cout << “test-- \n”; int tmp1=t1; int tmp2=t2; --t1;--t2; return test(tmp1,tmp2); } (续)
void maino test b(3, 4); ++b /t1=4:t2=5 b++ ∥/t1=5:t2=6 b /t1=4:t2=5 ∥tl=3;t2=4 在运算符重载中,++和-后缀运算符被看成一个二元运算符,在其参数类 表中有一个参数声明,但是在这个函数被调用时,这个参数值总为0,函 数内部不需要访问这个参数
void main() { test b(3,4); ++b; // t1=4;t2=5 b++; // t1=5;t2=6 --b; // t1=4;t2=5 b--; // t1=3;t2=4 } 在运算符重载中,++和--后缀运算符被看成一个二元运算符,在其参数类 表中有一个参数声明,但是在这个函数被调用时,这个参数值总为0,函 数内部不需要访问这个参数
19.1.2赋值运算符“=”的重载 对任一类X,如果没有用户自定义的赋值运算符函数,那么系 统自动地为其生成一个缺省的赋值运算符函数,定义为类X 中的成员到成员的赋值,例如: X&X: operator=(const X& source ∥.)成员间赋值 若obj和ob2是类X的两个对象,obj2已被创建,则编译程 序遇到如下语句: objl=obj2 就调用缺省的赋值运算符函数将对象0b2的数据成员的 值逐个赋给对象ob]1的对应数据成员中
19.1.2 赋值运算符“=”的重载 对任一类X,如果没有用户自定义的赋值运算符函数,那么系 统自动地为其生成一个缺省的赋值运算符函数,定义为类X 中的成员到成员的赋值,例如: X &X::operator=(const X& source) { //…成员间赋值 } 若obj1和obj2是类X的两个对象,obj2已被创建,则编译程 序遇到如下语句: obj1=obj2; 就调用缺省的赋值运算符函数,将对象obj2的数据成员的 值逐个赋给对象obj1的对应数据成员中
1指针悬挂问题 在某些特殊情况下,如类中有指针类型时,使用缺省 的赋值运算符函数会产生错误。 例192使用缺省的赋值运算符函数产生错误的例子。 #include #include class string i public: string char *s) ptr=new char[strlen(s)+1; strcpy(ptr; s);
1.指针悬挂问题 在某些特殊情况下,如类中有指针类型时,使用缺省 的赋值运算符函数会产生错误。 例19.2 使用缺省的赋值运算符函数产生错误的例子。 #include #include class string { public: string(char *s) { ptr=new char[strlen(s)+1]; strcpy(ptr,s); }
string i delete lptr;j void printo cout<<ptr<<end; y p rivate char *ptr, void maino string pl(book); string p2("pen"); p1=p2 cout<< p2 p2. printo cout<<" pl pl printo;
~string() { delete []ptr; } void print() { cout<<ptr<<endl; } private: char *ptr; }; void main() { string p1("book"); string p2("pen"); p1=p2; cout<<"p2:"; p2.print(); cout<<"p1:"; p1.print(); }
2.重载赋值运算符解决指针悬挂问题 为了解决上述使用缺省的赋值运算符所遇到的指针 悬挂问题,必须重载赋值运算符,使得对目标对象数据成员 指针的赋值,是把原对象指针ptr所指向的内容传递给它,而 不是简单地传递指针值。 例193重载赋值运算符解决指针悬挂问题。 # include≤ iostream. h> #include class string i public: string(char*s) i ptr=new char[strlen(s)+l; strcpy(ptr, s); astringe deleted ptr; void print(i cout<<ptr<<end; y
例19.3 重载赋值运算符解决指针悬挂问题。 #include #include class string { public: string(char *s) { ptr=new char[strlen(s)+1]; strcpy(ptr,s);} ~string(){ delete[] ptr; } void print(){ cout<<ptr<<endl; } 2. 重载赋值运算符解决指针悬挂问题 为了解决上述使用缺省的赋值运算符所遇到的指针 悬挂问题,必须重载赋值运算符,使得对目标对象数据成员 指针的赋值,是把原对象指针ptr所指向的内容传递给它,而 不是简单地传递指针值
string& operator=( const string&);/声明赋值运算符重载函数 private: char * ptr; string string: operator=(const string s) if(thiS=&s) return*this;∥防止s=s的赋值 delete l ptr; ∥释放掉原区域 ptr= new char[strlen(s.ptr)+1l;∥/分配新区域 strcpy(ptr,sptr); ∥字符串拷贝 return *this: void maino i string pl(book); string p2("pen"); 2 pipi cout<< p2: ; p2 print(; cout<<pl: pl printo;
string& operator=(const string&);//声明赋值运算符重载函数 private: char *ptr; }; string& string::operator=(const string& s) { if (this==&s) return *this; // 防止s=s的赋值 delete [] ptr; // 释放掉原区域 ptr=new char[strlen(s.ptr)+1]; // 分配新区域 strcpy(ptr,s.ptr); // 字符串拷贝 return *this; } void main() { string p1("book"); string p2("pen"); p1=p2; cout<<"p2:"; p2.print(); cout<<"p1:"; p1.print(); }