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;}


















































0 0
原创粉丝点击