C++运算符重载典型习题---复数类 String类 分数类

一、复数类(Complex class)

complex.cpp:

/*****************************************************
copyright (C), 2019-2020, Lighting Studio. Co.,     Ltd. 
File name:
Author:xozofunny    Version:0.1    Date: 
Description:
Funcion List: 
*****************************************************/

#include <iostream>
using namespace std;

class Complex{
private:
    float m_real;
    float m_imag;

public:
    
    Complex():m_real(0), m_imag(0){}
    Complex(float a, float b)
    {
        m_real = a;
        m_imag = b;
    }
    ~Complex(){}
    
    //以成员函数重载+
    Complex operator+(Complex &obj);
    Complex operator-(Complex &obj);
    Complex operator*(Complex &obj);
    Complex operator/(Complex &obj);
    
    //重载输入输出流只能用友元函数
    friend ostream& operator<<(ostream& out, Complex& obj);
    friend istream& operator>>(istream& in, Complex& obj);
	
    void show();

};

Complex Complex :: operator+(Complex &obj)//复数相加
{
    Complex tmp;
    tmp.m_real = m_real + obj.m_real;
    tmp.m_imag = m_imag + obj.m_imag;

    return tmp;
}

Complex Complex :: operator-(Complex &obj)//复数相减
{
    Complex tmp;
    tmp.m_real = m_real - obj.m_real;
    tmp.m_imag = m_imag - obj.m_imag;
    
    return tmp;
}

Complex Complex :: operator*(Complex &obj)//复数相乘
{
    Complex tmp;
    tmp.m_real = (m_real * obj.m_real) - (m_imag * obj.m_imag);
    tmp.m_imag = (m_imag * obj.m_real) + (m_real * obj.m_imag);
    
    return tmp;
}

Complex Complex:: operator/(Complex &obj)//复数相除
{
    Complex tmp;
    tmp.m_real = (((m_real * obj.m_real) + (m_imag * obj.m_imag)) / ((obj.m_real * obj.m_real) + (obj.m_imag * obj.m_imag)));
    tmp.m_imag = (((m_imag * obj.m_real) - (m_real * obj.m_imag)) / ((obj.m_real * obj.m_real) + (obj.m_imag * obj.m_imag)));

    return tmp;
}

void Complex :: show()//默认的public成员函数
{
    cout<<"result is "<<m_real<<"+"<<"j"<<m_imag<<endl;
}

//重载的输出流, 可以直接用来输出一个对象
ostream& operator<<(ostream& out, Complex& obj)//重载<<运算符
{
	if(obj != NULL)
		out<<obj.m_real<<" "<<"+"<<" "<<obj.m_imag<<"i";
	return out;
}

istream& operator>>(istream& in, Complex& obj)//重载>>运算符
{
    in>>obj.m_real>>obj.m_imag;
    return in;
}

int main()
{
    Complex obj1(2,3);
//两者占用不同的内存空间
    Complex obj2(4,5);

    Complex obj3 = obj1 + obj2;
    obj3.show();

    obj3 = obj2 - obj1;
    obj3.show();
	
    obj3 = obj2 * obj1;
    //obj3.show();
    cout<<obj3<<endl;

    obj3 = obj1 / obj2;
    //obj3.show();
    cout<<obj3<<endl;
	
    return 0;
}

 

测试结果:

二、string类

my_string.h

#ifndef __MYSTRING_H__
#define __MYSTRING_H__
 
#include <iostream>
using namespace std;
 
class MyString
{
    friend ostream & operator<<(ostream& out, const MyString& str);
    friend istream & operator>>(istream& in, MyString& str);
public:
	MyString();
    MyString(int len);
    MyString(const char *p);
    MyString(const MyString & str);
    ~MyString();
 
public:
    MyString& operator=(const char *p);
    MyString& operator=(MyString &str);
 
    char& operator[](const int index);
 
    bool operator==(const char *p) const;
    bool operator==(const MyString& str) const;
    bool operator!=(const char *p) const;
    bool operator!=(const MyString& str) const;
 
    bool operator<(const char *p) const;
    bool operator<(const MyString& str) const;
    bool operator>(const char *p) const;
    bool operator>(const MyString& str) const;
 
public:
    char *c_str()
    {
        return m_p;
    }
    const char *c_str2()
    {
        return m_p;
    }
 
    int length()
    {
        return m_len;
    }
 
private:
    int m_len;//字符串长度
    char *m_p;//所指字符串
};
 
 
#endif

my_string.cpp

#include "my_string.h"

MyString::MyString()//构造1,意旨只创建一个基对象,采用了默认参数
{
    cout<<"Default constructor was called"<<endl;
    m_len = 0;
    m_p = NULL;//它没有任何堆空间可言
}

MyString::MyString(int len)//告诉它默认分配一个固定的大小
{
    cout<<"Costum1 constructor was called"<<endl;
    m_len = len;
    m_p = new char[m_len];
}
MyString::MyString(const char *p)//给它初始化一个字符串
{
    cout<<"Costum2 constructor was called"<<endl;
    m_len = strlen(p);
    m_p = new char[m_len + 1];
    memcpy(m_p, p, m_len);
}
MyString::MyString(const MyString & str)//拷贝构造
{
    cout<<"Deepcopy constructor was called"<<endl;
    m_len = str.m_len;
    m_p = new char[m_len];
    memcpy(m_p, str.m_p, m_len*sizeof(char));
}

MyString::~MyString()//析构
{
    cout<<"Destructor was called"<<endl;
    delete[] m_p;
    m_len = 0;
    m_p = NULL;
}

//以全局变量创建的
//仅当当用一个对象输出时有效
ostream& operator<<(ostream& out, const MyString& str)
{
    if(str.m_p != NULL)
	out << str.m_p << ". and the length is:" << str.m_len;
    return out;
}

//仅当用一个对象输入时有效
//比如:MyString str;
//     cin>>str;//阻塞态
istream& operator>>(istream& in, MyString& str)
{
    char buf[255] = {0};//给它规定一个行缓冲,当且仅当用户输入回车时刷新
    in>>buf;
	
    if(buf != NULL)
    {
	str.m_len = strlen(buf);
	str.m_p = new char[str.m_len+1];
	memset(str.m_p, 0, sizeof(str.m_p));
	memcpy(str.m_p, buf, str.m_len);
    }
	
    return in;
}

//以成员函数重载
MyString& MyString:: operator=(const char *p)//将一个对象初始化为字符串常量
{
    if(m_p != NULL)
    {
	delete[] m_p;
	m_p = NULL;
	m_len = 0;
    }
    m_len = strlen(p);
    m_p = new char[m_len + 1];
    memcpy(m_p, p, m_len);

    return *this;
}

//使用一个已有的对象赋值给另一个新的对象, 初始化则调用拷贝构造
//例:MyString str2(str1);
MyString& MyString:: operator=(MyString &str)
{
    if(m_p != NULL)
    {
	delete[] m_p;
	m_p = NULL;
	m_len = 0;
    }
    m_len = str.length();//先计算相应的长度
    m_p = new char[m_len + 1];
    memcpy(m_p, str.c_str2(), m_len);

    return *this;
}

//以对象的形式下标访问相应的指定字符串
char& MyString:: operator[](const int index)
{
    if(index < 0 || index >= m_len)
    {
	cout<<"数组越界错误"<<endl;
	exit(-1);
    }
    return m_p[index];
}

/*****************************************
const表示不可对对象内存中的数据作任何改变
功能:判断两个字符串是否相等
******************************************/
bool MyString::operator==(const char *p) const
{
    if((size_t)m_len == (size_t)strlen(p))
    {
	if((strcmp(m_p, p) == 0))
	    return 1;
	else
	    return 0;
    }
    else
	return 0;
}

bool MyString::operator==(const MyString& str) const
{
    if(m_len == str.m_len)
    {
	if((strcmp(m_p, str.m_p) == 0))
	    return 1;
	else
	    return 0;
    }
    else
	return 0;
}

//长度不等,字符串的内容肯定不等
bool MyString::operator!=(const char *p) const
{
    if(((size_t)m_len != (size_t)strlen(p)))
	return 1;
    else
	return 0;
}

bool MyString::operator!=(const MyString& str) const
{
    if(((size_t)m_len != (size_t)str.m_len))
	return 1;
    else
	return 0;
}

//满足即说明这两个字符串没什么好比的,因为长度都不一样
bool MyString::operator<(const char *p) const
{
    if(((size_t)m_len != (size_t)strlen(p)))
	return 0;
    else
    {
	if((strcmp(m_p, p) < 0))
	    return 1;
	else
	    return 0;
    }
}

bool  MyString::operator<(const MyString& str) const
{
    if(((size_t)m_len != (size_t)str.m_len))
	return 0;
    else
    {
	if((strcmp(m_p, str.m_p) < 0))
	    return 1;
	else
	    return 0;
    }
}


bool MyString::operator>(const char *p) const
{
    if(((size_t)m_len != (size_t)strlen(p)))
        return 0;
    else
    {
	if((strcmp(m_p, p) > 0))
	    return 1;
	else
	    return 0;
    }
}

bool MyString::operator>(const MyString& str) const
{
    if(((size_t)m_len != (size_t)str.m_len))
	return 0;
    else
    {
	if((strcmp(m_p, str.m_p) > 0))
	    return 1;
	else
	    return 0;
    }
}

test.cpp

#include "my_string.h"

int main()
{
    MyString str1 = "we well we well rock you";
    cout<<str1<<endl;
    MyString str2;
    str2 = str1;
    cout<<str2<<endl;
    cout<<endl;
	
    if(str2 == str1)
	cout<<"Matching Good!"<<endl;
    else
	cout<<"Dismatching!"<<endl;
    cout<<endl;
	
    cin>>str1;
    cin>>str2;
    MyString str3 = str2;//copyconstructor
    cout<<"str1 = "<<str1<<endl;
    cout<<"str2 = "<<str2<<endl;
    cout<<"str3 = "<<str3<<endl;

    cout<<"str2 = str1??"<<endl;
    if(str2 == str1)
	cout<<"Matching Good!"<<endl;
    else
	cout<<"Dismatching!"<<endl;
    cout<<"str2 > str1??"<<endl;
    if(str2 > str1)
	cout<<"Matching Good!"<<endl;
    else
	cout<<"Dismatching!"<<endl;
    cout<<"str2 < str1??"<<endl;
    if(str2 < str1)
	cout<<"Matching Good!"<<endl;
    else
	cout<<"Dismatching!"<<endl;
	
    return 0;
}

测试结果:

阻塞了:

现在开始输入hello world(注意中间有空格)

cin输入的流会将空格作为划分标志,我输入了一行,程序中下一行cin调用却不堵塞了,是因为我的缓冲区是行缓冲,下次读取时直接从缓冲区中读取一个字符串了。。 完现了 scanf("%s", str); 的功能。

C++实现分数类---实现分数的加减乘除,与比较赋值运算;

成员函数重载分数比较与运算, 全局函数借助成员函数重载完成整数与分数的比较与运算。

分子分母能够实现约分, 求倒数。

Grade.h

#ifndef _GRADE_H_
#define _GRADE_H_

#include <iostream>

using namespace std;

class Grade{
protected:
    int numerator;
    int denominator;
    int GCD(int a, int b = 1);//最大公约数

public:
    Grade();
    Grade(int a, int b);//构造
    ~Grade();//析构
//以成员函数的方式重载分数之间的运算
    Grade operator+(Grade& obj);
    Grade operator-(Grade& obj);
    Grade operator*(Grade& obj);
    Grade operator/(Grade& obj);
	
    Grade& operator=(const Grade& obj);//以成员函数形式重载赋值符号
    Grade& operator-();//重载单目运算符"-"

//重载分数之间的比较
    bool operator==(Grade& obj);
    bool operator!=(Grade& obj);
    bool operator>(Grade& obj);
    bool operator<(Grade& obj);
    bool operator>=(Grade& obj); 
    bool operator<=(Grade& obj);

	
//以全局函数重载输入输出流
    friend ostream& operator<<(ostream& obj, Grade& obj);
    friend istream& operator>>(istream& obj, Grade& obj);
//相关成员函数
    void Reduction();//约分
    void Redata();//倒数

//以全局函数的形式计算比较整数和分数
    friend Grade operator+(int a, Grade& obj);
    friend Grade operator-(int a, Grade& obj);
    friend Grade operator*(int a, Grade& obj);
    friend Grade operator/(int a, Grade& obj);

    friend bool operator==(int a, Grade& obj);
    friend bool operator!=(int a, Grade& obj);
    friend bool operator>(int a, Grade& obj);
    friend bool operator>=(int a, Grade& obj);
    friend bool operator<(int a, Grade& obj);
    friend bool operator<=(int a, Grade& obj);
	
};             

#endif

Grade.cpp

#include "Grade.h"

inline int ABS(int m)
{
    return (m >= 0 ? m : -m);
}

Grade::Grade()
{
    numerator = 0;
    denominator = 1;//不允许分母为0
    cout<<"Default constructor was called"<<endl;
}

Grade::Grade(int a, int b = 1)//构造
{
    if((a >= 0 && b > 0) || (a <= 0 && b< 0))
    {
	numerator = ABS(a);
	denominator = ABS(b);
    }
    else{
	numerator = -ABS(a);
	denominator = ABS(b);
    }
    cout<<"Costum constructor was called"<<endl;
}

//最大公约数不会大于两者之间最小的一个数
int Grade::GCD(int a, int b)
{
    if(a >= b)
    {
	for(int i = b; i > 0; i--)
	{
	    if(b%i == 0 && a%i == 0)
	    {
		return i;
		break;
	    }		
	}
    }
    else
    {
	for(int i = a; i > 0; i--)
	{
	    if(a%i==0 && b%i==0)
	    {
                return i;
		break;
	    }
	}
    }
}

Grade Grade::operator+(Grade& obj)
{
    Grade tmp;
    tmp.numerator = (this->numerator * obj.denominator)+(this->denominator * obj.numerator);
    tmp.denominator = this->denominator * obj.denominator;

    tmp.Reduction();//约分处理
    return tmp;
}

Grade Grade::operator-(Grade& obj)
{
    Grade tmp;
    tmp.numerator = (this->numerator * obj.denominator)-(this->denominator * obj.numerator);
    tmp.denominator = this->denominator * obj.denominator;

    tmp.Reduction();
    return tmp;
}
Grade Grade::operator*(Grade& obj)
{
    Grade tmp;
    tmp.numerator = this->numerator * obj.numerator;
    tmp.denominator = this->denominator * obj.denominator;

    tmp.Reduction();
    return tmp;
}
Grade Grade::operator/(Grade& obj)
{
    Grade tmp;
    tmp.numerator = this->numerator * obj.denominator;
    tmp.denominator = this->denominator * obj.numerator;

    tmp.Reduction();
    return tmp;
}

Grade& Grade::operator=(const Grade& obj)//以成员函数形式重载赋值符号
{
    this->numerator = obj.numerator;
    this->denominator = obj.denominator;

    return *this;
}

Grade& Grade::operator-()//重载单目运算符"-"
{
    numerator = -numerator;

    return *this;
}

bool Grade::operator==(Grade& obj)
{
    if((numerator*obj.denominator) == (denominator*obj.numerator))
	return 1;
    else
	return 0;
}

bool Grade::operator!=(Grade& obj)
{
    if((numerator*obj.denominator) != (denominator*obj.numerator))
	return 1;
    else
	return 0;
}

bool Grade::operator>(Grade& obj)
{
    if((numerator*obj.denominator) > (denominator*obj.numerator))
	return 1;
    else
	return 0;
}

bool Grade::operator>=(Grade& obj)
{
    if((numerator*obj.denominator) >= (denominator*obj.numerator))
	return 1;
    else
	return 0;
}


bool Grade::operator<=(Grade& obj)
{
    if((numerator*obj.denominator) <= (denominator*obj.numerator))
	return 1;
    else
	return 0;
}

bool Grade::operator<(Grade& obj)
{
    if((numerator*obj.denominator) < (denominator*obj.numerator))
	return 1;
    else
	return 0;
}


void Grade::Redata()//求倒数
{
    if(numerator > 0)
    {
	int tmp = numerator;
	numerator = denominator;
	denominator = tmp;
    }

    if(numerator < 0)
    {
	int tmp = numerator;
	numerator = -denominator;
	denominator = ABS(tmp);
    }
}

void Grade::Reduction()//约分,用来输出
{
    int gcd = GCD(ABS(numerator), ABS(denominator));
    if(gcd > 1)
    {
	denominator /= gcd;
	numerator /= gcd;
    }
//分子分母同时大于0,或者分子分母同时小于0
    if((numerator >= 0 && denominator > 0) || (numerator <= 0 && denominator < 0))
    {
        numerator = ABS(numerator);
	denominator = ABS(denominator);
    }
    else{
	numerator = -ABS(numerator);
	denominator = ABS(denominator);
    }
}

ostream& operator<<(ostream& out, Grade& obj)
{
    if(obj.numerator == 0)
	out<<"The Finally Fraction is:"<<obj.numerator;
    else if(obj.denominator != 1)
	out<<"The Finally Fraction is:"<<obj.numerator<<"/"<<obj.denominator;
    else
	out<<"The Finally Fraction is:"<<obj.numerator;

    return out;
}

istream& operator>>(istream& in, Grade& obj)
{
    cout<<"input numerator"<<endl<<">>>:";
    cin>>obj.numerator;
    cout<<"input denominator"<<endl<<">>>:";
    cin>>obj.denominator;
    while(obj.denominator == 0)
    {
	cin>>obj.denominator;
    }

    if(obj.denominator < 0)
    {
	obj.numerator = -ABS(obj.numerator);
	obj.denominator = ABS(obj.denominator);
    }
    return in;
}

/**************************************************
全局的友元函数将会调用对象中重载过的运算符直接
将整形变量转换构造成相应的分母分子形式,分母的值
始终为1,两对象之间会调用上方的比较重载函数
*************************************************/
Grade operator+(int a, Grade& obj)
{
    return Grade(a)/*因为构造函数是默认参数*/ + obj; 
}

Grade operator-(int a, Grade& obj)
{
    return Grade(a) - obj;
}

Grade operator*(int a, Grade& obj)
{
    return Grade(a) * obj;
}

Grade operator/(int a, Grade& obj)
{
    return Grade(a) / obj;
}

bool operator==(int a, Grade& obj)
{
    return Grade(a) == obj;
}

bool operator!=(int a, Grade& obj)
{
    return Grade(a) != obj;
}

bool operator>(int a, Grade& obj)
{
    return Grade(a) > obj;
}

bool operator>=(int a, Grade& obj)
{
    return Grade(a) >= obj;
}

bool operator<(int a, Grade& obj)
{
    return Grade(a) < obj;
}

bool operator<=(int a, Grade& obj)
{
    return Grade(a) <= obj;
}


Grade::~Grade()//析构
{
    cout<<"Destructor was called"<<endl;
}

main.cpp

#include "Grade.h"

int main()
{
    Grade obj1(3,4);
    Grade obj2;
    int tmp = 7;

    cout<<"obj1 = "<<obj1<<endl;
    cin>>obj2;
    cout<<"obj2 = "<<obj2<<endl;

    Grade obj3 = obj1 + obj2;
    cout<<obj3<<endl;
    obj3 = obj1 - obj2;
    cout<<obj3<<endl;
    obj3 = obj1 * obj2;
    cout<<obj3<<endl;
    obj3 = obj1 / obj2;
    cout<<obj3<<endl;
    
    obj3 = tmp + obj1;
    cout<<obj3<<endl;
    obj3 = tmp - obj1;
    cout<<obj3<<endl;
    obj3 = tmp * obj1;
    cout<<obj3<<endl;
    obj3 = tmp / obj1;
    cout<<obj3<<endl;

    if(obj1 == obj2)
	cout<<"Matching!"<<endl;
    else
	cout<<"Sorry Dismatching!"<<endl;
    if(obj1 > obj2)
	cout<<"Matching!"<<endl;
    else
	cout<<"Sorry Dismatching!"<<endl;
    if(obj1 != obj2)
	cout<<"Matching!"<<endl;
    else
	cout<<"Sorry Dismatching!"<<endl;
	
	
    return 0;
}

Makefile

.PHONY : clean
cc = g++
CFLAGS =  -g -Wall
Target = main
BIN = Grade.o  main.o
$(Target) : $(BIN)
    $(cc) -o  $@  $^
%.o : %.cpp
    $(cc) $(CFLAGS) -c $< -o $@
clean:
    rm -f $(BIN)
    rm -i main

结果:

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值