您的位置:首页 > 编程语言 > C语言/C++

C++友元函数以及运算符重载

2014-03-29 09:50 155 查看
一、友元函数的作用

函数的私有和保护变量在类内可以访问,在类外只可访问公有变量;派生类在类内只可访问其基类的公有变量和保护变量,在类外只可访问其公有变量(要看具体的继承类型);

因此,在有些情况下,需要访问类的私有或保护变量时,不得不调用其成员函数,因为只有成员函数才有访问的权限。因而多出许多时间开销。

友元函数和类的成员函数的访问权限相同,但是其不是类的成员函数,它破坏了类的封装性;友元函数分为三类:普通的友元函数,友元类,和类的成员函数成为友元函数;

因为友元函数没有this指针,则参数要有三种情况:
2.1.1 要访问非static成员时,需要对象做参数;
2.1.2 要访问static成员或全局变量时,则不需要对象做参数;
2.1.3 如果做参数的对象是全局对象,则不需要对象做参数;
(1)普通友元函数:常用的就是运算符重载

#include <iostream>
using namespace std;

class time
{
friend ostream& operator<<(ostream&,time& t);
private:
int x;
int y;
int z;

public:
time(int a,int b,int c):x(a),y(b),z(c){};
};

ostream& operator<<(ostream& out,time& t)
{
out<<"("<<t.x<<t.y<<t.z<<")";
return out;
}
int main()
{
time t(1,2,3);
cout<<t<<endl;

return 0;
}

友元函数的位置是无关紧要的;

(2)友元类

#include <iostream>
using namespace std;
class A;
class time
{
friend ostream& operator<<(ostream&,time& t);
private:
int x;
int y;
int z;

public:
time(int a,int b,int c):x(a),y(b),z(c){};
friend A;
};

class A
{
private:
int m;
int n;
public:

void test(time& t);
};
void A::test(time& t)
{
m=t.x;
n=t.y;
}
ostream& operator<<(ostream& out,time& t)
{
out<<"("<<t.x<<t.y<<t.z<<")";
return out;
}
int main()
{
time t(1,2,3);
cout<<t<<endl;
A a;
a.test(t);

return 0;
}

使用单个声明使A类的所有函数成为类X的友元,它提供一种类之间合作的一种方式,使类A的对象可以具有类A和类time的功能

(3)类A的一个成员函数成为类B的友元函数

#include <iostream>
using namespace std;
class time;
class A
{
private:
int m;
int n;
public:
void test(time& t);
};

class time
{
friend void A::test(time& t);
friend ostream& operator<<(ostream&,time& t);
private:
int x;
int y;
int z;

public:
time(int a,int b,int c):x(a),y(b),z(c){};

};

void A::test(time& t)
{
m=t.x;
n=t.y;
}
ostream& operator<<(ostream& out,time& t)
{
out<<"("<<t.x<<t.y<<t.z<<")";
return out;
}
int main()
{
time t(1,2,3);
cout<<t<<endl;
A a;
a.test(t);

return 0;
}


注意:此时类A的定义一定要在类time之前,此时test()函数的声明在类time之前,方为正确的,若在之后定义,则test()即使声明为友元函数,依然无法访问其私有变量;

ps:刚刚写的时候,利用头文件和cpp文件进行封装,在操作符重载函数前加了个inline 即

inline ostream& operator<<(ostream& out,time& t)
{
return out<<"("<<t.x<<t.y<<t.z<<")";

}
将它放在了cpp文件中,总是报错,后将其和头文件放在一起,就没有错误了;


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: