This commit is contained in:
Light-City
2020-04-06 00:57:02 +08:00
parent f97c156cc4
commit a4d828bb4c
120 changed files with 4413 additions and 0 deletions

View 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");
}

View 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");
}

View File

@@ -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");
}

View 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");
}

View 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

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}