运算符重载(友缘,友元)"/>
CPPDay04运算符重载(友缘,友元)
目录
1.为什么要重载运算符:
2.运算符的本质:函数
3.如何重载运算符
4.友缘,友元
5.输出运算符重载
6. 一般运算符重载的规范:
7. 哪些运算符不能重载
8.运算符重载分类
9.运算符重载需知:
1.为什么要重载运算符:
我们希望自己抽象出来的类也可以使用运算符去操作。
2.运算符的本质:函数
3.如何重载运算符
函数名:
operator 运算符名
参数列表:
双目运算符 两个参数
单目运算符 一个参数
三目运算符不能重载
如果运算符重载函数是类的成员函数,那么 参数列表少一个。
返回值:
所有运算符重载函数,都有且只有一个返回值。
1.18 2.987
18 + 987 ==
4.友缘,友元
有类A,A的成员函数可以访问私有成员变量。如果有一个函数func不是A的成员函数,这个函数中能否访问类A的成员变量?不能。如果声明函数func是类A的友元函数,那么函数func中可以访问A类对象的私有成员。
5.输出运算符重载
cout << 某个对象
6. 一般运算符重载的规范:
双目运算符 一般 重载为友元
单目运算符 一般 重载为成员
7. 哪些运算符不能重载
?:
::
. ->
&
数组的[]
8.运算符重载分类
- 算术运算符: + - * / % + -
- 输入输出运算符:>> <<
- 位运算符:
- 自运算符:++ ++ -- --
- 关系运算符: > < == != !
- 逻辑运算符:
- * 解引用:
- 泛型
- 赋值运算符重载:
- 编译器会自动帮我们写。
- 只能重载为成员
- 动态内存分配重载:new delete new[] delete[]
9.运算符重载需知:
1.重载后的运算符功能应该和本来的相同
2.不能自定义
3.不能改变运算符优先级
// 算术运算符重载.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <iostream>
using namespace std;
//小数类
class xiaoshu{int zheng;int xiao;
public:xiaoshu(){ cout << "构造器" << endl; zheng = xiao = 0; }xiaoshu(int z, int x) :zheng(z), xiao(x){ cout << "有参构造器" << endl; }xiaoshu operator+(const xiaoshu& xs);//const;//"operator+"这个整体就是函数名,该成员函数是小数类的对象在调用,xs1+xs2其实是xs1.+xs2省略了点,所以本来需要两个形参,现在只要一个就够了//如果形参是 xiaoshu 类型,那么在传参的时候,就会临时构造出一个 xiaoshu类型的对象来储存实参的副本,增加了空间复杂度。//并且要在xiaoshu &xs前加上const ,这样就不能给xs赋值,来改变xs和它的别名的值了,保护xs2//在函数后加上const 表名该函数为const成员函数,不能在函数内修改该类成员变量的值,保护xs1//该函数的返回值是小数类型的一个临时对象,且加上const 表示该临时对象不能修改。(不加const也没有关系)
private:int _jia(int a, int b);int _getWeiShu(int a););//求一个整数有多少个位的函数
// bool _isJinWei()//判断是否进位
public:void setZheng(int z){ this->zheng = z; }void setXiao(int x){ this->xiao = x; }
};//求一个整数有多少个位
int xiaoshu::_getWeiShu(int a){int count = 0;while (a){a /= 10;count++;}return count;
}int xiaoshu::_jia(int a, int b){//最高位相加int aWeiShu = _getWeiShu(a);int bWeiShu = _getWeiShu(b);if (aWeiShu == bWeiShu) return a + b;if (aWeiShu > bWeiShu){for (int i = 0; i < (aWeiShu - bWeiShu); i++)b *= 10;return a + b;}for (int i = 0; i < (bWeiShu - aWeiShu); i++)a *= 10;return a + b;
}xiaoshu xiaoshu::operator+(const xiaoshu& xs){xiaoshu temp; //temp.xiao=this->xiao +xs.xiao;不能直接加,必须判断小数的位数,比如1.17+1.189不鞥17+189,必须先判断位数
// temp.xiao = this->xiao + xs.xiao;temp.setXiao( _jia(xiao, xs.xiao) );temp.setZheng(this->zheng + xs.zheng );return temp;
}int _tmain(int argc, _TCHAR* argv[])
{xiaoshu xs1(2,345), xs2(2,3);xiaoshu xs3 = xs1 + xs2;while (1);return 0;
}
// 输出运算符重载.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"#include <iostream> // istream:输入流类 对应cin这个对象 ostream:输出流类 对应cout这个类
using namespace std;class Fenshu{int fenzi;int fenmu;
public:Fenshu(){fenzi = 0;fenmu = 1;cout << "无参构造" << endl;}Fenshu(int fenzi, int fenmu) :fenzi(fenzi), fenmu(fenmu){cout << "有参构造" << endl;}friend ostream& operator<<(ostream& o, const Fenshu& fs);friend istream& operator>>(istream& i, Fenshu& fs);
};//重载输出运算符
ostream& operator<<(ostream& o,const Fenshu& fs){//该函数的左值是cout,所以第一个参数应该是ostream类对象的引用,右值是fs,所以第二个参数就是Fenshu类对象的引用,两个参数的位置不可替换//operator<<函数的返回值是 ostream输出类的对象的引用,也就是cout这个输出类对象。return o << fs.fenzi << " / " << fs.fenmu;
}
/*
cout是个流对象,或者说是ostream这个类的对象,该类内部有输出缓冲区,当执行cout << x的时候,其实就是调用了ostream的operator<< 方法,该方法是对<<运算符的重载,该方法的参数即是x。
operator<<方法返回ostream类的引用,即该类对象自身,所以cout << x 语句可以做左值,即支持连续调用: cout << x << y.....
x变量内容拷贝到缓冲区中,ostream内部会根据某种缓冲机制(全缓冲,行缓冲,无缓冲)将缓冲区的内容输出到屏幕终端。*/
//重载输入运算符
istream& operator>>(istream& i,Fenshu& fs){char c;return i >> fs.fenzi >> c >> fs.fenmu;
}int main(){Fenshu fs1(3, 4);cout << fs1 << endl;cin >> fs1;cout << fs1 << endl;cout << 1 << 3 << 4 << 5;while (1);return 0;
}#if 0
class A{int a;
public:void setA(int a){ this->a = a; }//声明函数func是本类的友元函数friend void func(A& a);
};void func(A& a){cout << a.a << endl;
}int _tmain(int argc, _TCHAR* argv[])
{A aa;aa.while (1);return 0;
}#endif
// 自运算符重载.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <iostream> // istream:输入流对象 cin ostream:输出流对象 cout
using namespace std;
class Fenshu{int fenzi;int fenmu;
public:Fenshu(){fenzi = 0;fenmu = 1;cout << "无参构造" << endl;}Fenshu(int fenzi, int fenmu) :fenzi(fenzi), fenmu(fenmu){cout << "有参构造" << endl;}friend ostream& operator<<(ostream& o, const Fenshu& fs);friend istream& operator>>(istream& i, Fenshu& fs);//后自增 n++ Fenshu operator++(int);//前自增 ++nFenshu operator++();//关系运算符重载friend bool operator>(const Fenshu& fs1, const Fenshu& fs2);//赋值运算符重载Fenshu& operator=(const Fenshu& fs2);
};Fenshu& Fenshu::operator = (const Fenshu& fs2){cout << "赋值运算符重载" << endl;this->fenzi = fs2.fenzi;this->fenmu = fs2.fenmu;return *this;
}bool operator>(const Fenshu& fs1, const Fenshu& fs2){int fz1 = fs1.fenzi * fs2.fenmu;int fz2 = fs2.fenzi * fs1.fenmu;return (fz1 > fz2);
}//后自增 n++ 先参与运算,再自增
Fenshu Fenshu::operator++(int){Fenshu fs = *this;fenzi = fenzi + fenmu; return fs;
}
//前自增 ++n 先自增,再参与运算
Fenshu Fenshu::operator++(){fenzi = fenzi + fenmu;return *this;
}//重载输出运算符
ostream& operator<<(ostream& o, const Fenshu& fs){return o << fs.fenzi << " / " << fs.fenmu;
}
//重载输入运算符
istream& operator>>(istream& i, Fenshu& fs){char c;return i >> fs.fenzi >> c >> fs.fenmu;
}int _tmain(int argc, _TCHAR* argv[])
{Fenshu fs(1, 2);Fenshu fs1(2, 6);Fenshu fs2(3, 9);fs = fs1 = fs2;cout << (fs > fs1) << endl;cout << fs << endl;cout << fs++ << endl;cout << fs << endl;cout << ++fs << endl;while (1);return 0;
}
// new运算符重载.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
//内存泄漏: 申请了堆内存却没有及时释放
//越界:数组越界 访问了数组之外的内存段class MyString{char* pBuff;size_t size;
public:MyString(){ pBuff = NULL; size = 0; }MyString(char* str){int len = strlen(str);pBuff = new char[len + 1];memcpy(pBuff, str, sizeof(char)* (len + 1) );size = len;}void* operator new(size_t len);void* operator new[](size_t len);void operator delete[](void* p, size_t len);void operator delete(void* p,size_t len);~MyString(){if (pBuff){delete[] pBuff;}pBuff = NULL;size = 0;}
};void MyString::operator delete(void* p,size_t len){printf("释放%d字节内存段!\n",len);free(p);
}
void* MyString::operator new(size_t len){printf("开辟%d字节内存段!\n", len);return malloc(len);
}void MyString::operator delete[](void* p, size_t len){printf("释放%d字节内存段!\n", len);printf("使用的是中括号\n");free(p);
}
void* MyString::operator new[](size_t len){printf("开辟%d字节内存段!\n", len);printf("使用的是中括号\n");return malloc(len);
}int _tmain(int argc, _TCHAR* argv[])
{MyString* pStr = new MyString("hello");MyString* pStr2 = new MyString[5] ;delete[] pStr2;delete pStr;while (1);return 0;
}
更多推荐
CPPDay04运算符重载(友缘,友元)
发布评论