一、复数类(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
结果:
、