第四周学习
来源:互联网 发布:九珠数学算法视频教程 编辑:程序博客网 时间:2024/06/15 14:00
4.1运算符重载
- 对已有的运算符赋予多重的含义
- 使同一运算符作用于不同类型的数据时能够有不同的功能
- 扩展c++中运算符的功能
5+4=9
5+6i+7+3i=12+9i - 运算符重载的实质是函数的重载
返回值类型 operator 运算符(形参表){…}
class complex{public: complex(int a,int b){real=a;imag=b;} int real,imag; complex operator+(const complex& a){ return complex(real+a.real,imag+a.imag)}//重载为成员函数的时候只需要一个参量。}; complex::complex operator+(const complex &a,const complex &b){ return complex(a.real+b.real,a.imag+b.imag)}//重载为普通函数的时候为两个参量,为运算符目数。两者是等价的
4.2赋值运算符 = 的重载
- 可以将赋值运算符重载为想要的功能,比如把int赋值给complex等。
- 赋值运算符 = 只能重载为成员函数
e.g 自己的string类
#include <iostream>using namespace std;class String{private: char *str;public: String():str(NULL){} const char *c_str(){return str;} char *operator =(const char *s); ~String(); String(const char *s1){ str=new char[strlen(s1)+1]; strcpy(str,s1);//用*char可以完成,strcpy做的是拷贝的工作,将后者拷贝给前者 }};char *String::operator=(const char *s){ if(str) delete[] str; if(s){ str=new char[strlen(s)+1]; strcpy(str,s); }else{ str=NULL; } return str;}String::~String(){ if(str) delete[] str;}int main(){ String s; s="good sdf";//为了满足这个等号,需要对赋值运算符进行重载 String s2="hello lsidfh"; cout<<s.c_str()<<endl;//s.c_str()目的是返回一个*char cout<<s2.c_str()<<endl; return 0;}
深拷贝和浅拷贝
- 当自己不定义复制构造函数的时候,系统会自动生成一个复制构造函数,将原有的内容一字节一字节的拷贝给新的对象。
- 但有时候,我们并不希望如此,当对象的成员变量有指针的时候,会出现以下情况:a对象和b对象的指针内容在相同的内存空间中,则可以通过b对象的成员指针改变a对象的内容,这不是我们想要的
- 于是有了深拷贝,需要对新对象的指针对象开辟新的空间,并复制原来对象的内容进去,这样,虽然先后两个对象的指针变量指的内容是一致的,但在内存空间中是不同的位置,不会相互影响
4.3运算符重载为友元函数
- 成员函数不能满足使用需求,而普通函数不能访问类私有成员
例如,现有一个类名叫complex,要实现complex+5,可以通过成员函数的重载实现,这句话等于complex.+(5),但若想要实现5+complex,需要对整体的 + 进行重载,就不能是成员函数,而是要普通函数,而普通函数不能访问类的私有成员,所以只能是友元函数才可以。
class complex{private: double real,imag;public: complex(double r, double i):real(r),imag(i){}; complex operator+ (double r){ return complex(real+r,imag); }//对于后置的加号,只要通过成员函数即可实现};int main(){ complex a(2,3),b(1,1); b=a+5;//完成后置加号的重载 return 0;}
对于前置加号,只能通过重载为友元实现
class complex{private: double real,imag;public: complex(double r, double i):real(r),imag(i){}; complex operator+ (double r){ return complex(real+r,imag); }friend complex operator+ (double r,const complex& c);//申明友元函数};complex operator+ (double r,const complex& c){ return complex(c.real+r,c.imag);}//定义普通函数operator+int main(){ complex a(2,3),b(1,1); b=a+5; b=5+a; return 0;}
4.4 e.g.可变长整形数组
- 需求,编写一个程序,完成动态可变数组,需要多大的数组,就可以扩大成为那么大的。
需要实现的c++主程序:
int main(){ CArray a;//创建一个可变数组对象 for(int i=0;i<5;++i){ a.push_back(i);//支持push_back函数加入新的元素 } CArray a2,a3; a2=a;//可以通过等号进行深拷贝 for(int i=0;i<a.length();++i){ cout<<a2[i]<<" ";//支持流输出运算符 } a2=a3; for(int i=0;i<a2.length();++i){ cout<<a2[i]<<" "; } cout<<endl; a[3]=100;//支持直接调用 CArray a4(a);//支持这样构造 for(int i=0;i<a4.length();++i){ cout<<a4[i]<<" "; } return 0;}
实现:
#include <iostream>using namespace std;class CArray{public: int *a1; int size; void push_back(const int &a){//将新的地址加上新的元素赋值给旧的 int *p2; int *p1; int *a3; a3=a1; p1=new int[size+1]; p2=p1; for(int i=0;i<size;++i){ *p2=*a3; ++p2; ++a3; } *p2=a; ++size; a1=p1; delete p1; } CArray (CArray &a){//深拷贝 size=a.size; int *p1; int *p2; p1=new int[size]; p2=p1; for(int i=0;i<size;++i){ *p2=*(a.a1+i); ++p2; } a1=p1; delete [] p1; } CArray(){size=0;} int length(){return size;} int & operator[](int i){//实现[]调用 return a1[i]; } ~CArray(){//检查是否还有未删除的指针 if(a1){delete [] a1;} }};int main(){ CArray a; for(int i=0;i<5;++i){ a.push_back(i); } CArray a2,a3; a2=a; for(int i=0;i<a.length();++i){ cout<<a2[i]<<" "; } a2=a3; for(int i=0;i<a2.length();++i){ cout<<a2[i]<<" "; } cout<<endl; a[3]=100; CArray a4(a); for(int i=0;i<a4.length();++i){ cout<<a4[i]<<" "; } return 0;}
4.5流插入运算符和流提取运算符的重载
- 若想输出或者输入某个类,就要对其进行重载,重载为ostream/istream的引用
e.g.
假设c是complex复数类的对象,现在希望写 “cout<
#include <iostream>using namespace std;class Complex{private: double real,imag;public:Complex(int a=0,int b=0):real(a),imag(b){}friend ostream &operator<<(ostream & o,const Complex &s);friend istream &operator>>(istream & o,Complex &s);//申明友元的重载};ostream &operator<<(ostream & o,const Complex &s){ o<<s.real<<"+"<<s.imag<<"i"; return o;}istream &operator>>(istream & o,Complex &c){ string s; o>>s; int pos=s.find("+",0); string stmp=s.substr(0,pos); c.real=atof(stmp.c_str()); stmp=s.substr(pos+1,s.length()-pos-2); c.imag=atof(stmp.c_str()); return o;}int main(){ Complex c; int n; cin>>c>>n; cout<<c<<","<<n; return 0;}
4.6自加/自减运算符的重载
- 自加自减运算符分前置后置分别进行重载
- 前置运算符作为一元运算符重载
重载为成员函数时,变量减一
- T operator++();
- T operator–();
重载为全局函数,变量为一
- T operator++(T);
- T operator–(T);
后置运算符作为二元运算符重载
- 重载为成员函数时候,变量减一,多写一个参数,具体无意义
- T operator++(int)
- T operator–(int)
- 重载为全局函数的时候,有两个变量
- T operator++(T, int)
- T operator–(T, int)
#include <iostream>using namespace std;class cdemo{private: int a;public: friend ostream &operator<<(ostream &o,cdemo &s); cdemo(int i):a(i){} cdemo &operator ++(){//前置,不需要加变量 a++; return *this; } cdemo &operator ++(int){//后置,需要加个变量 cdemo tmp(*this); a++; return tmp; }};ostream &operator<<(ostream &o,cdemo &s){//流输出重载 o<<s.a; return o;}int main(){ cdemo d(5); cout<<(d++)<<","; cout<<d<<",", cout<<(++d)<<","; cout<<d<<endl; cout<<(d--)<<"," cout<<d<<","; cout<<(--d)<<"," cout<<d<<","; cout<<d<<endl; return 0;}
阅读全文
0 0
- 第四周 学习目标
- Linux学习第四周
- 机器学习第四周
- 第四周学习
- 第四周学习笔记
- 第四周学习
- 第四周学习内容
- 第四周Android学习笔记
- 启明星第四周学习总结
- VB学习第四周--字符函数验证
- 第四周作业:数学学习工具!
- Stanford机器学习---第四周.神经网络模型
- 吴恩达机器学习笔记_第四周
- Android学习的第四周笔记
- [Boolan] C++第四周学习笔记
- 第四周Linux课堂学习(1)
- 第四周Linux课堂学习(2)
- GeekBand C++第四周学习笔记
- LeetCode39 Combination Sum
- quartz
- Python列表和字典的学习
- 为什么研发名片扫描识别?
- AND 感知器练习
- 第四周学习
- JDK,JRE,JVM,三者,你知道它们的关系么
- 加密对象到locastorage / 从 locastorage解密对象
- win10开启自带移动热点以及解决无法设置移动热点,请打开WLAN问题
- hibernate
- Linux文件权限详解
- mybatis
- PAT甲级真题及训练集(17)--1052. Linked List Sorting (25)
- Mysql 中的sql_safe_update