update
This commit is contained in:
25
practical_exercises/10_day_practice/day7/()运算符/重载()的时钟.cpp
Normal file
25
practical_exercises/10_day_practice/day7/()运算符/重载()的时钟.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
class Time{
|
||||
private:
|
||||
int hh,mm,ss;
|
||||
public:
|
||||
Time(int h=0,int m=0,int s=0):hh(h),mm(m),ss(s){}
|
||||
void operator()(int h,int m,int s) {
|
||||
hh=h;
|
||||
mm=m;
|
||||
ss=s;
|
||||
}
|
||||
void ShowTime(){
|
||||
cout<<hh<<":"<<mm<<":"<<ss<<endl;
|
||||
}
|
||||
};
|
||||
int main(){
|
||||
Time t1(12,10,11);
|
||||
t1.ShowTime();
|
||||
t1.operator()(23,20,34);
|
||||
t1.ShowTime();
|
||||
t1(10,10,10);
|
||||
t1.ShowTime();
|
||||
system("pause");
|
||||
}
|
||||
16
practical_exercises/10_day_practice/day7/=号运算符/=例题.cpp
Normal file
16
practical_exercises/10_day_practice/day7/=号运算符/=例题.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
//例题ch.cppi
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
class X{
|
||||
public:
|
||||
X &operator = (const X & x)
|
||||
{cout << "a:"; return *this;};
|
||||
};
|
||||
int main ()
|
||||
{
|
||||
X obj1, obj2, obj3;
|
||||
obj1 = obj2; //调用重载“=”
|
||||
obj1.operator= (obj2); //调用重载“=”
|
||||
obj1 = obj2 = obj3; //调用重载“=”
|
||||
system("pause");
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
class X
|
||||
{public:
|
||||
int operator() (int i=0)
|
||||
{ cout << "X::operator(" << i << ")" << endl; return i; };
|
||||
int operator() (int i, int j)
|
||||
{ cout << "X::operator(" << i << "," << j << ")" << endl;
|
||||
return i; };
|
||||
int operator[] (int i)
|
||||
{ cout << "X::operator[" << i << "]" << endl; return i; };
|
||||
int operator[] (char * cp)
|
||||
{ cout << "X::operator[" << cp << "]" << endl; return 0; };
|
||||
};
|
||||
int main (void)
|
||||
{ X obj; int i = obj (obj (1), 2);
|
||||
int a = obj[i]; int b = obj["abcd"];
|
||||
cout<<"a="<<a<<endl;
|
||||
cout<<"b="<<b<<endl;
|
||||
system("pause");
|
||||
}
|
||||
50
practical_exercises/10_day_practice/day7/[]运算符/[]例题(重点).cpp
Normal file
50
practical_exercises/10_day_practice/day7/[]运算符/[]例题(重点).cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
//Eg8-9.cpp
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
using namespace std;
|
||||
struct Person{ //职工基本信息的结构
|
||||
double salary;
|
||||
char *name;
|
||||
};
|
||||
class SalaryManaege{
|
||||
Person *employ; //存放职工信息的数组
|
||||
int max; //数组下标上界
|
||||
int n; //数组中的实际职工人数
|
||||
public:
|
||||
SalaryManaege(int Max=0){
|
||||
max=Max;
|
||||
n=0;
|
||||
employ=new Person[max];
|
||||
}
|
||||
double &operator[](char *Name) { //重载[],返回引用
|
||||
Person *p;
|
||||
for(p=employ;p<employ+n;p++)
|
||||
//如果存在处理
|
||||
if(strcmp(p->name,Name)==0)
|
||||
return p->salary;
|
||||
//不存在情况处理
|
||||
p=employ + n++;
|
||||
p->name=new char[strlen(Name)+1];
|
||||
strcpy(p->name,Name);
|
||||
p->salary=0;
|
||||
return p->salary;
|
||||
}
|
||||
|
||||
void display(){
|
||||
for(int i=0;i<n;i++)
|
||||
cout<<employ[i].name<<" "<<employ[i].salary<<endl;
|
||||
}
|
||||
};
|
||||
int main(){
|
||||
SalaryManaege s(3);
|
||||
s["张三"]=2188.88;
|
||||
s["里斯"]=1230.07;
|
||||
s["王无"]=3200.97;
|
||||
cout<<"张三\t"<<s["张三"]<<endl; cout<<"里斯\t"<<s["里斯"]<<endl;
|
||||
cout<<"王无\t"<<s["王无"]<<endl;
|
||||
|
||||
cout<<"-------下为display的输出--------\n\n";
|
||||
s.display();
|
||||
system("pause");
|
||||
}
|
||||
|
||||
145
practical_exercises/10_day_practice/day7/readme.md
Normal file
145
practical_exercises/10_day_practice/day7/readme.md
Normal file
@@ -0,0 +1,145 @@
|
||||
运算符重载是C++的一项强大功能。通过重载,可以扩展C++运算符的功能,使它们能够操作用户自定义的数据类型,增加程序代码的直观性和可读性。
|
||||
|
||||
本章主要介绍 类成员运算符重载与友元运算符重载, 二元运算符与一元运算符重载, 运算符++、--、[]、()重载, this指针与运算符重载及 流运算符<<和>>的重载
|
||||
|
||||
一、重载二元运算符
|
||||
|
||||
1、二元运算符的调用形式与解析
|
||||
|
||||
aa@bb 可解释成 aa.operator@(bb)
|
||||
或解释成 operator@(aa,bb)
|
||||
|
||||
如果两者都有定义,就按照重载解析
|
||||
|
||||
```c++
|
||||
class X{
|
||||
public:
|
||||
void operator+(int);
|
||||
X(int);
|
||||
};
|
||||
void operator+(X,X);
|
||||
void operator+(X,double);
|
||||
```
|
||||
2、类运算符重载形式
|
||||
|
||||
(1)非静态成员运算符重载
|
||||
|
||||
以类成员形式重载的运算符参数比实际参数少一个,第1个参数是以this指针隐式传递的。
|
||||
|
||||
```c++
|
||||
class Complex{
|
||||
double real,image;
|
||||
public:
|
||||
Complex operator+(Complex b){……}
|
||||
......
|
||||
};
|
||||
```
|
||||
(2) 友元运算符重载
|
||||
|
||||
如果将运算符函数作为类的友元重载,它需要的参数个数就与运算符实际需要的参数个数相同。比如,若用友元函数重载Complex类的加法运算符,则形式如下:
|
||||
|
||||
```c++
|
||||
class Complex{
|
||||
……
|
||||
friend Complex operator+(Complex a,Complex b); //声明
|
||||
//......
|
||||
};
|
||||
|
||||
Complex operator+(Complex a,Complex b){……} //定义
|
||||
```
|
||||
|
||||
二、重载一元运算符
|
||||
|
||||
1、一元运算符
|
||||
|
||||
一元运算符只需要一个运算参数,如取地址运算符(&)、负数(?)、自增加(++)等。
|
||||
|
||||
2、一元运算符常见调用形式为:
|
||||
|
||||
@a 或 a@ //隐式调用形式
|
||||
|
||||
a.operator@() // 显式调用一元运算符@
|
||||
|
||||
其中的@代表一元运算符,a代表操作数。
|
||||
|
||||
@a代表前缀一元运算,如“++a”;
|
||||
|
||||
a@表示后缀运算,如“a++”。
|
||||
|
||||
3、@a将被C++解释为下面的形式之一
|
||||
|
||||
a.operator@()
|
||||
|
||||
operator@(a)
|
||||
|
||||
4.一元运算符作为类成员函数重载时不需要参数,其形式如下:
|
||||
|
||||
```c++
|
||||
class X{
|
||||
……
|
||||
T operator@(){……};
|
||||
}
|
||||
```
|
||||
T是运算符@的返回类型。从形式上看,作为类成员函数重载的一元运算符没有参数,但实际上它包含了一个隐含参数
|
||||
|
||||
即调用对象的this指针。
|
||||
|
||||
5.前自增(减)与后自增(减)
|
||||
|
||||
C++编译器可以通过在运算符函数参数表中是否插入关键字int 来区分这两种方式
|
||||
|
||||
```c++
|
||||
//前缀
|
||||
operator -- ();
|
||||
operator -- (X & x);
|
||||
//后缀
|
||||
operator -- (int);
|
||||
operator -- (X & x, int);
|
||||
```
|
||||
三、重载赋值运算符=
|
||||
|
||||
1、赋值运算符“=”的重载特殊性
|
||||
|
||||
赋值运算进行时将调用此运算符
|
||||
|
||||
只能用成员函数重载
|
||||
|
||||
如果需要而没有定义时,编译器自动生成,该版本进行bit-by-bit拷贝
|
||||
|
||||
四、重载赋值运算符[]
|
||||
|
||||
1、[ ]是一个二元运算符,其重载形式如下:
|
||||
|
||||
```c++
|
||||
class X{
|
||||
……
|
||||
X& operator[](int n);
|
||||
};
|
||||
```
|
||||
2、重载[]需要注意的问题
|
||||
- []是一个二元运算符,其第1个参数是通过对象的this指针传递的,第2个参数代表数组的下标
|
||||
- 由于[]既可以出现在赋值符“=”的左边,也可以出现在赋值符“=”的右边,所以重载运算符[]时常返回引用。
|
||||
- **[]只能被重载为类的非静态成员函数,不能被重载为友元和普通函数**。
|
||||
|
||||
五、重载( )
|
||||
|
||||
1、运算符( )是函数调用运算符,也能被重载。且只能被重载为类的成员函数。
|
||||
|
||||
2、运算符( )的重载形式如下:
|
||||
|
||||
```c++
|
||||
class X{
|
||||
……
|
||||
X& operator( )(参数表);
|
||||
};
|
||||
```
|
||||
|
||||
其中的参数表可以包括任意多个参数。
|
||||
|
||||
3、运算符( )的调用形式如下:
|
||||
|
||||
X Obj; //对象定义
|
||||
|
||||
Obj()(参数表); //调用形式1
|
||||
|
||||
Obj(参数表); //调用形式2
|
||||
76
practical_exercises/10_day_practice/day7/一元运算符/秒钟自增运算.cpp
Normal file
76
practical_exercises/10_day_practice/day7/一元运算符/秒钟自增运算.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
//设计一个时间类Time,它能够完成秒钟的自增运算。
|
||||
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
class Time{
|
||||
private:
|
||||
int hour,minute,second;
|
||||
public:
|
||||
Time(int h,int m, int s);
|
||||
Time operator++();
|
||||
//友元重载需要参数
|
||||
friend Time operator--(Time &t);
|
||||
void display();
|
||||
};
|
||||
|
||||
Time::Time(int h, int m, int s){
|
||||
hour=h;
|
||||
minute=m;
|
||||
second=s;
|
||||
if (hour>=24)
|
||||
hour=0;
|
||||
if (minute>=60)
|
||||
minute=0;
|
||||
if (second>=60)
|
||||
second=0;
|
||||
}
|
||||
|
||||
Time Time::operator++(){
|
||||
++second;
|
||||
if (second>=60){
|
||||
second=0;
|
||||
++minute;
|
||||
if(minute>=60){
|
||||
minute=0;
|
||||
++hour;
|
||||
if(hour>=24)
|
||||
hour=0;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Time operator--(Time &t){
|
||||
--t.second;
|
||||
if (t.second>=60){
|
||||
t.second=0;
|
||||
++t.minute;
|
||||
if(t.minute>=60){
|
||||
t.minute=0;
|
||||
++t.hour;
|
||||
if(t.hour>=24)
|
||||
t.hour=0;
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
void Time::display(){
|
||||
cout<<hour<<":"<<minute<<":"<<second<<endl;
|
||||
}
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
Time t1(23,59,59);
|
||||
t1.display();
|
||||
++t1; //隐式调用
|
||||
t1.display();
|
||||
t1.operator++(); //显式调用
|
||||
t1.display();
|
||||
Time t2(24,60,60);
|
||||
t2.display();
|
||||
++t2;
|
||||
t2.display();
|
||||
--t2;
|
||||
t2.display();
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
47
practical_exercises/10_day_practice/day7/一元运算符/计数器前后自增.cpp
Normal file
47
practical_exercises/10_day_practice/day7/一元运算符/计数器前后自增.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
//设计一个计数器counter,用类成员重载自增运算符实现计数器的自增,用友元重载实现计数器的自减。
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
class Counter{
|
||||
private:
|
||||
int n;
|
||||
public:
|
||||
Counter(int i=0):n(i){};
|
||||
Counter operator++();
|
||||
Counter operator++(int);
|
||||
friend Counter operator--(Counter &c);
|
||||
friend Counter operator--(Counter &c,int);
|
||||
void display();
|
||||
};
|
||||
Counter Counter::operator++(){
|
||||
++n;
|
||||
return *this;
|
||||
}
|
||||
Counter Counter::operator++(int){
|
||||
n++;
|
||||
return *this;
|
||||
}
|
||||
Counter operator--(Counter &c){
|
||||
--c.n;
|
||||
return c;
|
||||
}
|
||||
Counter operator--(Counter &c,int){
|
||||
c.n--;
|
||||
return c;
|
||||
}
|
||||
void Counter::display(){
|
||||
cout<<"counter number="<<n<<endl;
|
||||
}
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
Counter a;
|
||||
++a;
|
||||
a.display();
|
||||
a++;
|
||||
a.display();
|
||||
--a;
|
||||
a.display();
|
||||
a--;
|
||||
a.display();
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
67
practical_exercises/10_day_practice/day7/二元运算符/1.类运算符重载.cpp
Normal file
67
practical_exercises/10_day_practice/day7/二元运算符/1.类运算符重载.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
//有复数类Complex,利用运算符重载实现复数的加、减、乘、除等复数运算。
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
class Complex {
|
||||
private:
|
||||
double r,i;
|
||||
public:
|
||||
Complex(double R=0,double I=0):r(R),i(I){};
|
||||
Complex operator+(Complex b);
|
||||
Complex operator-(Complex b);
|
||||
Complex operator*(Complex b);
|
||||
Complex operator/(Complex b);
|
||||
void display();
|
||||
};
|
||||
|
||||
Complex Complex::operator +(Complex b)
|
||||
{
|
||||
return Complex(r+b.r,i+b.i);
|
||||
}
|
||||
Complex Complex::operator -(Complex b)
|
||||
{
|
||||
return Complex(r-b.r,i-b.i);
|
||||
}
|
||||
//求复数相乘的算法
|
||||
Complex Complex::operator *(Complex b)
|
||||
{
|
||||
Complex t;
|
||||
t.r=r*b.r-i*b.i;
|
||||
t.i=r*b.i+i*b.r;
|
||||
return t;
|
||||
}
|
||||
//求复数相除的算法
|
||||
Complex Complex::operator /(Complex b) {
|
||||
Complex t;
|
||||
double x;
|
||||
x=1/(b.r*b.r+b.i*b.i);
|
||||
t.r=x*(r*b.r+i*b.i);
|
||||
t.i=x*(i*b.r-r*b.i);
|
||||
return t;
|
||||
}
|
||||
void Complex::display(){
|
||||
cout<<r;
|
||||
if (i>0) cout<<"+";
|
||||
if (i!=0) cout<<i<<"i"<<endl;
|
||||
//}display();
|
||||
};
|
||||
|
||||
int main(void) {
|
||||
Complex c1(1,2),c2(3,4),c3,c4,c5,c6;
|
||||
Complex a,b(2,3);
|
||||
a=b+2; //正确
|
||||
// a=2+b; //错误
|
||||
a.display();
|
||||
c3=c1+c2;
|
||||
c4=c1-c2;
|
||||
c5=c1*c2;
|
||||
c6=c1/c2;
|
||||
c1.display();
|
||||
c2.display();
|
||||
c3.display();
|
||||
c4.display();
|
||||
c5.display();
|
||||
c6.display();
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
|
||||
84
practical_exercises/10_day_practice/day7/二元运算符/2.友元运算符实现.cpp
Normal file
84
practical_exercises/10_day_practice/day7/二元运算符/2.友元运算符实现.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
|
||||
/*
|
||||
在C++的标准命名空间std中预定义了复数类Complex,
|
||||
并且通过友元重载了Complex的各种运算,包括本程序中重载的+、-、*、/。
|
||||
若使用using namespace std将std名字空间引入本程序,
|
||||
则本程序中的Complex将与std名字空间中的Complex类的运算符重载函数产生冲突,引起编译错误。
|
||||
*/
|
||||
/*
|
||||
对于不要求左值且可以交换参数次序的运算符(如+、-、*、/ 等运算符),
|
||||
最好用非成员形式(包括友元和普通函数)的重载运算符函数实现。
|
||||
*/
|
||||
|
||||
//解决前面的2+b问题。
|
||||
#include<iostream>
|
||||
|
||||
|
||||
class Complex{
|
||||
private:
|
||||
double r,i;
|
||||
public:
|
||||
Complex(double R=0,double I=0):r(R),i(I){};
|
||||
friend Complex operator+(Complex a, Complex b);
|
||||
friend Complex operator-(Complex a, Complex b);
|
||||
friend Complex operator*(Complex a, Complex b);
|
||||
friend Complex operator/(Complex a, Complex b);
|
||||
|
||||
friend Complex operator+(Complex a,double b){
|
||||
return Complex(a.r+b,a.i);
|
||||
}
|
||||
friend Complex operator+(double a,Complex b){
|
||||
return Complex(a+b.r,b.i);
|
||||
}
|
||||
|
||||
void display();
|
||||
};
|
||||
|
||||
Complex operator+(Complex a, Complex b){
|
||||
return Complex(a.r+b.r,a.i+b.i);
|
||||
}
|
||||
Complex operator-(Complex a, Complex b){
|
||||
return Complex(a.r-b.r,a.i-b.i);
|
||||
}
|
||||
Complex operator*(Complex a, Complex b){
|
||||
Complex t;
|
||||
t.r = a.r*b.r-a.i*b.i;
|
||||
t.i = a.r*b.i+a.i*b.r;
|
||||
}
|
||||
Complex operator/(Complex a, Complex b){
|
||||
Complex t;
|
||||
double x;
|
||||
x = 1/(b.r*b.r+b.i*b.i);
|
||||
t.r = x*(a.r*b.r+a.i*b.i);
|
||||
t.i = x*(a.i*b.r-a.r*b.i);
|
||||
return t;
|
||||
}
|
||||
|
||||
void Complex::display(){
|
||||
std::cout<<r;
|
||||
if(i>0)
|
||||
std::cout<<"+";
|
||||
if(i!=0)
|
||||
std::cout<<i<<"i"<<std::endl;
|
||||
}
|
||||
int main(void) {
|
||||
Complex c1(1,2),c2(3,4),c3,c4,c5,c6;
|
||||
Complex a,b(2,3);
|
||||
Complex a1=b+2;
|
||||
Complex a2=2+b;
|
||||
a1.display();
|
||||
a2.display();
|
||||
c3=c1+c2;
|
||||
c4=c1-c2;
|
||||
c5=c1*c2;
|
||||
c6=c1/c2;
|
||||
c1.display();
|
||||
c2.display();
|
||||
c3.display();
|
||||
c4.display();
|
||||
c5.display();
|
||||
c6.display();
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
|
||||
70
practical_exercises/10_day_practice/day7/综合例题/重要.cpp
Normal file
70
practical_exercises/10_day_practice/day7/综合例题/重要.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
//设计一个字符串类String,通过运算符重载实现字符串的输入、输出以及+=、==、!=、<、>、>=、[ ]等运算。
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
using namespace std;
|
||||
class String {
|
||||
private:
|
||||
int length; //字符串长度
|
||||
char *sPtr; //存放字符串的指针
|
||||
void setString( const char *s2);
|
||||
friend ostream &operator<<(ostream &os, const String &s);
|
||||
friend istream &operator>>(istream &is, String &s); //重载输入运算符
|
||||
public:
|
||||
String( const char * = "" );
|
||||
const String &operator=(const String &R); //重载赋值运算符 =
|
||||
const String &operator+=(const String &R); //字符串的连接 +=
|
||||
bool operator==(const String &R); //字符串的相等比较 ==
|
||||
bool operator!=(const String &R); //字符串的不等比较 !=
|
||||
bool operator!() ; //判定字符串是否为空
|
||||
bool operator<(const String &R) const; //字符串的小于比较 <
|
||||
bool operator>(const String &R); //字符串的大于比较 >
|
||||
bool operator>=(const String &R); //字符串的大于等于比较
|
||||
char &operator[](int); //字符串的下标运算
|
||||
~String();
|
||||
};
|
||||
const String &String::operator+=(const String &R) {
|
||||
char *temp = sPtr;
|
||||
length += R.length;
|
||||
sPtr = new char[length+1];
|
||||
strcpy(sPtr,temp );
|
||||
strcat(sPtr,R.sPtr );
|
||||
delete [] temp;
|
||||
return *this;
|
||||
}
|
||||
bool String::operator==(const String &R){return strcmp(sPtr,R.sPtr)==0;}
|
||||
bool String::operator!=(const String & R){return !(*this==R);}
|
||||
bool String::operator!(){return length ==0;}
|
||||
bool String::operator<(const String &R)const{return strcmp(sPtr,R.sPtr)<0;}
|
||||
bool String::operator>(const String &R){return R<*this;}
|
||||
bool String::operator>=(const String &R){return !(*this<R);}
|
||||
char &String::operator[](int subscript){return sPtr[subscript];}
|
||||
int main(){
|
||||
String s1("happy"),s2("new year"),s3;
|
||||
cout << "s1 is " << s1 << "\ns2 is " << s2 << "\ns3 is " << s3
|
||||
<< "\n比较s2和s1:"
|
||||
<< "\ns2 ==s1结果是 " << ( s2 == s1 ? "true" : "false")
|
||||
<< "\ns2 != s1结果是 " << ( s2 != s1 ? "true" : "false")
|
||||
<< "\ns2 > s1结果是 " << ( s2 > s1 ? "true" : "false")
|
||||
<< "\ns2 < s1结果是 " << ( s2 < s1 ? "true" : "false")
|
||||
<< "\ns2 >= s1结果是 " << ( s2 >= s1 ? "true" : "false");
|
||||
cout << "\n\n测试s3是否为空: ";
|
||||
if (!s3){
|
||||
cout << "s3是空串"<<endl; //L3
|
||||
cout<<"把s1赋给s3的结果是:";
|
||||
s3 = s1;
|
||||
cout << "s3=" << s3 << "\n"; //L5
|
||||
}
|
||||
cout << "s1 += s2 的结果是:s1="; //L6
|
||||
s1 += s2;
|
||||
cout << s1; //L7
|
||||
|
||||
cout << "\ns1 += to you 的结果是:"; //L8
|
||||
s1 += " to you";
|
||||
cout << "s1 = " << s1 <<endl; //L9
|
||||
s1[0] = 'H';
|
||||
s1[6] = 'N';
|
||||
s1[10] = 'Y';
|
||||
cout << "s1 = " << s1 << "\n"; //L10
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user