成员函数和全局函数
先看一段下面的代码:
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函数获取private
cout << 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;
}