Day14.成员函数和全局函数//链表货物类//友元函数//操作符重载相关
来源:互联网 发布:asp编程培训 编辑:程序博客网 时间:2024/05/20 00:37
成员函数和全局函数
先看一段下面的代码:
class Test1{public:int a;int b;public:Test1(int a, int b){this->a = a;this->b = b;}};Test1 T_add(Test1 &t1, Test1 &t2){Test1 t3;t3.a = t1.a + t2.a;t3.b = t1.b + t2.b;return t3;}假设上面的代码是可以执行的,且没有其他的错误,这时候F7编译就会提示错误:
error C2512: “Test1”: 没有合适的默认构造函数可用错误在Test1 t3这里,没有合适的构造函数,如何解决呢??
解决办法:
//全局函数Test1 T_add(Test1 &t1, Test1 &t2){ Test1 t3; t3.a = t1.a + t2.a; t3.b = t1.b + t2.b; return t3;}
public:Test1(int a=0, int b=0){this->a = a;this->b = b;}//成员函数Test1 T_add(Test1 &t1, Test1 &t2){Test1 t3;t3.a = t1.a + t2.a;t3.b = t1.b + t2.b;return t3;}给出完整的代码;
#include "iostream"using namespace std;class Test{public: int a; int b;public: //构造函数 Test(int a=0, int b=0) { this->a = a; this->b = b; }public: //成员函数 Test M_add( Test &t2) { this->a = this->a + t2.a; this->b = this->b + t2.b; return *this; } void print() { cout << a << endl; cout << b << endl; }};//全局函数Test G_add(Test &t1, Test &t2){ Test t3; t3.a = t1.a + t2.a; t3.b = t1.b + t2.b; return t3;}void main(){ Test t1(1, 2), t2(3, 4); Test t3; //全局函数 t1 = G_add( t1 , t2); t1.print(); //成员函数 t1.M_add(t2); t1.print(); system("pause");}成员函数如何变成全局函数?
全局函数如何变成成员函数?
根据Day13天的学习,我们知道在构造函数调用时,C++编译器是这样改变的:
Test(int a=0, int b=0){this->a = a;this->b = b;}Test(Test *pthis, int a, int b){this->a = a;this->b = b;}
会自动加上this指针,这就是全局函数和成员函数的定义上的区别。
总计:
1. 从成员函数转化为全局函数,只需要加一个this指针(指向本类的类指针)
2. 从全局函数转化为类的成员函数时,需要减一个左操作数参数(第一个参数)
链表货物类
例子;某商店经销一种货物。货物购进和卖出时以箱为单位,各箱的重量不一样,因此,商店需要记录目前库存的总重量。现在用C++模拟商店货物购进和卖出的情况。
#include "iostream"using namespace std;class Goods{private:int weight;static int total_weight;public:Goods(int w){weight = w;total_weight += w;}int getweight(){return weight;}static int gettotalweight(){return total_weight;}Goods *next;};int Goods::total_weight = 0;void buy(Goods * &f, Goods * &r, int w){Goods *p = new Goods(w);p->next = NULL;if (f == NULL) f = r = p;else{r->next = p;r = r->next;}}void sale(Goods * &f, Goods * &r){if (f == NULL){cout << "there are no more goods" << endl;return;}Goods *q = f;f = f->next;delete q;cout << "saled." << endl;}void main(){Goods *head = NULL, *end = NULL;int w, choice;do{cout << "Key 0 is over \nKey 1 is buy \nKey 2 is sale" << endl;cout << "please enter your choice:" << endl;cin >> choice;switch (choice){case 1:cout << "enter weight:" << endl;cin >> w;buy(head, end, w);break;case 2:cout << "sale begin" << endl;sale(head, end);cout << "sale end:" << endl;break;case 0:break;}cout << "Now total weights are:" << Goods::gettotalweight() << endl;} while (choice);system("pause");}
友元函数类
友元函数可以通过函数参数访问类的private成员变量
普通函数如何访问私有成员变量呢?
#include "iostream"using namespace std;class Test{private:int a;int b;public:Test(int a, int b){this->a = a;this->b = b;}int geta(){return a;}friend int func(Test *p, int a);};int func(Test *p, int a){p->a = a;return p->a;}void main(){Test t1(1,2);//通过get函数获取privatecout << t1.geta() << endl;//通过friend友元函数cout<<func(&t1, 10)<<endl;system("pause");}这是友元函数,下面看友元类:
class A{friend class B;private: int x;public:void print(){cout << x << endl;}};class B{private:A AObj;public:void set(int i){AObj.x = i;}void print(){AObj.print();}};void main(){B Bobj;Bobj.set(10);Bobj.print();system("pause");}
运算符重载
不能重载的运算符: . :: .* ?: sizeof
首先打个桩,基础的代码写出来:
#include "iostream"using namespace std;class complex{public:int a;int b;public:complex(int a = 0, int b = 0){this->a = a;this->b = b;}void print(){cout << a << "+" << b << "i" << endl;}};complex comadd(complex &c1, complex &c2){complex tmp;tmp.a = c1.a + c2.a;tmp.b = c1.b + c2.b;return tmp;}void main(){//int是基础类型,C++编译器已经实现了+int a = 10;int b = 20;a = a + b;complex c1(1, 2), c2(3, 4);//complex是一个自定义类型,C++不知道如何+//但是C++编译器会提供一个机制,让你实现自定义类型+complex c3 = comadd(c1, c2);c3.print();system("pause");}
继续深化:
#include "iostream"using namespace std;class complex{public:int a;int b;public:complex(int a = 0, int b = 0){this->a = a;this->b = b;}void print(){cout << a << "+" << b << "i" << endl;}};//complex comadd(complex &c1, complex &c2)complex operator+(complex &c1, complex &c2){complex tmp;tmp.a = c1.a + c2.a;tmp.b = c1.b + c2.b;return tmp;}void main(){//int是基础类型,C++编译器已经实现了+int a = 10;int b = 20;a = a + b;complex c1(1, 2), c2(3, 4);//complex是一个自定义类型,C++不知道如何+//但是C++编译器会提供一个机制,让你实现自定义类型+//第一步:函数实现complex c3 = comadd(c1, c2);//第二步:operator实现complex c3 = operator+(c1, c2);//第三部:+实现complex c3 = c1+c2;c3.print();system("pause");}总结:
1.运算符函数是一种特殊的成员函数或友元函数
2.成员函数的语法形式为:
类型 类名::operator op(参数表)
{*******************************}
3.一个运算符被重载后,原有意义没有失去,只是定义了相对一特定类的一个新运算符
用成员函数或友元函数重载运算符
1. 成员函数实现,如上面的代码实现的;
2.如果成员函数为private私有成员,用友元函数实现,只需要在类的定义中加上:
class complex{public:int a;int b;************}
int a;int b;friend complex operator+(complex &c1, complex &c2);3.全局函数实现比较简单, 如何使用成员函数实现呢????
目标:通过类的成员函数,完成操作符重载
1 要承认操作符重载是一个函数,要写函数原型
2 写出函数调用语言
c1.operator - c2;
3 完善函数原型
complex operator-(complex &c2)
完整的代码实现:
#include "iostream"using namespace std;class complex{private:int a;int b;friend complex operator+(complex &c1, complex &c2);public:complex(int a = 0, int b = 0){this->a = a;this->b = b;}void print(){cout << a << "+" << b << "i" << endl;}complex operator-(complex &c2){complex tmp;tmp.a = tmp.a - c2.a;tmp.b = tmp.b - c2.b;return tmp;}};//complex comadd(complex &c1, complex &c2)complex operator+(complex &c1, complex &c2){complex tmp;tmp.a = c1.a + c2.a;tmp.b = c1.b + c2.b;return tmp;}void main(){//int是基础类型,C++编译器已经实现了+int a = 10;int b = 20;a = a + b;complex c1(1, 2), c2(3, 4);//complex是一个自定义类型,C++不知道如何+//但是C++编译器会提供一个机制,让你实现自定义类型+//第一步:函数实现//complex c3 = comadd(c1, c2);//第二步:operator实现//complex c3 = operator+(c1, c2);//第三部:+实现complex c3 = c1+c2;c3.print();//第二步:operator//complex c4 = c1.operator-(c2);//第三步:-实现complex c4 = c1 - c2;c4.print();system("pause");}
还有前置++,后置++, 前置--,后置--,具体内容看视频,我过了。。
http://pan.baidu.com/s/1kTnFb8N
http://pan.baidu.com/s/1mglBgqk
总结:
留个例子吧,建立一个描述三维坐标的类Tri_coor,重载运算符“+” “++” “=”,实现简单的算术运算。
答案:
C++中不能用友元函数重载的运算符有: = () [ ] ->
项目开发中运算符重载的重点和难点
以 [ ] 为例,看下面的两句代码:
for(int i=0; i<a1.length(); i++) { a1.setData(i, i); //a[i] = 1; } for(int i=0; i<a1.length(); i++) { printf("array %d: %d\n", i, a1.getData(i));// printf("array %d: %d\n", i, a1[i])); }要使用[ ]实现操作符的重载,见注释中。
a1[i]要这样改写
int operator= (int i)
但是如果直接这样实现这句:
a[i] = 1;就会出现问题,左操作数必须为左值,这时候记住一句话:
函数返回值当左值,需要返回一个引用
int& operator= (int i)完整的功能代码,给出下载地址:
http://pan.baidu.com/s/1ntzMlQT
总结一下代码:
//通过类的成员函数实现-操作complex operator-(complex &c2){complex tmp;tmp.a = this->a - c2.a;tmp.b = b - c2.b;return tmp;}complex operator+(complex &c2){complex tmp;tmp.a = this->a + c2.a;tmp.b = b + c2.b;return tmp;}
//前置--complex& operator--(){this->a--;this->b--;return *this;}//前置++complex& operator--(){this->a++;this->b++;return *this;}
//后置--complex operator--(int){complex tmp = *this;this->a--;this->b--;return tmp;}//后置++complex operator--(int){complex tmp = *this;this->a++;this->b++;return tmp;}
- Day14.成员函数和全局函数//链表货物类//友元函数//操作符重载相关
- 操作符重载:类成员函数和全局函数
- 【C/C++学院】(8)全局函数和类成员函数转化/友元/操作符重载
- 操作符重载为成员函数还是友元函数?
- 重载运算符之友元函数和成员函数
- 运算符重载函数作为类成员函数和友元函数
- 运算符重载函数作为类成员函数和友元函数
- C++运算符重载函数作为类成员函数和友元函数
- 运算符重载函数作为类成员函数和友元函数
- C++运算符重载函数作为类成员函数和友元函数
- 10.2 运算符重载函数作为类成员函数和友元函数
- 全局函数、类成员函数 作为友元函数
- Day41、静态成员变量、静态成员函数、单例模式、成员/成员函数指针、操作符重载、友元函数
- 重载操作符为成员函数和全局函数对于做操作数的限制
- C++ 友元函数和非成员运算符重载
- C++实现输入输出运算符重载、友元函数和成员函数实现复数类Complex
- 成员函数重载运算符和友元函数重载运算符的比较
- 成员函数重载运算符和友元函数重载运算符的比较
- ios的category
- Sqoop使用和简介
- 400+考研 北京航空航天大学6系计算机学院961计算机专业技术基础资料合辑
- 教程——Basys3开发板的MicroBlaze串口实验
- 让程序员跳槽的非钱原因
- Day14.成员函数和全局函数//链表货物类//友元函数//操作符重载相关
- java学习之旅41--面向对象_14_继承_super_构造器的调用_继承的内存分析(非常重要)
- 垃圾回收算法
- 黑马程序员---Java集合的使用
- JS页面截图技术
- 400+考研 北京航空航天大学7系机械工程及自动化学院971机械工程综合资料合辑
- oracle和sql server中回车符和换行符的sql代码
- NSNotificationCenter管理
- 第二章 Spring MVC入门 —— 跟开涛学SpringMVC