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

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

2016-08-17 18:13 399 查看
这个问题来源于自学C++primer自我实践

**

重载运算符

**

在c++中不止函数可以重载,运算符也可以重载。由于一般数据类型间的运算符没有重载的必要,所以运算符重载主要是面向对象之间的

在进行对象之间的运算时,程序会调用与运算符相对应的函数进行处理,所以运算符重载有两种方式:成员函数和友元函数。成员函数的形式比较简单,就是在类里面定义了一个与操作符相关的函数。友元函数因为没有this指针,所以形参会多一个。

**

运算符重载时要遵循以下规则:

**

(1) 除了类属关系运算符"."、成员指针运算符".*"、作用域运算符"::"、sizeof运算符和三目运算符"?:"以外,C++中的所有运算符都可以重载。

(2) 重载运算符限制在C++语言中已有的运算符范围内的允许重载的运算符之中,不能创建新的运算符。

(3) 运算符重载实质上是函数重载,因此编译程序对运算符重载的选择,遵循函数重载的选择原则。

(4) 重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符操作数的个数及语法结构。

(5) 运算符重载不能改变该运算符用于内部类型对象的含义。它只能和用户自定义类型的对象一起使用,或者用于用户自定义类型的对象和内部类型的对象混合使用时。

(6) 运算符重载是针对新类型数据的实际需要对原有运算符进行的适当的改造,重载的功能应当与原有功能相类似,避免没有目的地使用重载运算符。


我试了试加法运算的重载,下面直接上简单的实例

**类A的.h文件**
#ifndef A_H
#define A_H
class A
{
public:
A();
A(int d):data(d){}
int getData(){return data;}

A operator+(A&);//成员函数
friend A operator+(const A&,const A&);//友元函数

friend void printString(const A &data);// 另一个友元函数的实例

private:
int data;
};
#endif // A_H


**类A的.cpp文件**
#include "a.h"
#include "qDebug"
#include "friend.h"
A::A()
{

}
//友元函数的形式
A operator+(const A &a1,const A &a2)
{
qDebug()<<"friend add";
printString(a1);
return A(a1.data+a2.data);
}
//成员函数的形式
A A::operator+(A &a)
{
qDebug()<<"A add";
return A(data+a.data);
}


将友元函数单独放在另外一个头文件中
#ifndef FRIEND
#define FRIEND
#include "a.h"
#include "qdebug.h"
void printString(const A &data)
{
qDebug()<<"printString"<<data.data;
}
#endif // FRIEND


在main函数中调用
#include "mainwindow.h"
#include <QApplication>
#include "a.h"
#include "QDebug"
int main(int argc, char *argv[])
{
//    QApplication a(argc, argv);
//    MainWindow w;
//    w.show();
//生成类A的对象
A a1(1),a2(2),a3(3);
qDebug()<<a1.getData()<<a2.getData()<<a3.getData();
//使用加法运算符,对于重载的加法运算符有两个,一个是定义成友元函数,一个是成员函数,
//函数体内会有debug输出
//[1]
a1 = a2+a3;
qDebug()<<a1.getData();
//[1]
//[2]
operator +(a2,a3);
//[2]
//[3]
a1.operator +(a3);
//[3]
return 1;
}


输出结果



可以知道,[1]处调用的是成员函数的加法运算符,[2]处是手动调用的友元函数加法运算符,[3]处是手动调用的成员函数加法运算符

这一部分可以参考这篇文章

**

友元函数

**

类可以允许其他类或者函数访问它 的 非公有成员(protected,private),方法就是使其他类或者函数成为它的友元。

在类中的友元声明只是指定了访问权限,并不是通常意义上的函数声明,如果我们希望类的用户能够使用某个友元,我们必须在在友元声明之外,对函数再一次进行声明。。。为了使友元对类可见,我们通常把友元函数声明与类本身放在同一个文件中。也就是说上面friend.h文件应该放在a.h中但在类的定义外部,这样类的用户就可以使用printString()函数。。而我是直接在a.cpp中包含头文件friend.h,,效果是一样的。

在上面的输出中, 我们也看到了 “printString 2 “的输出字样,这就是友元函数的加法运算符函数中调用了printString(); 并且在main中operator +(a2,a3); 所以打印出来的a2.data 也就是 2

注意:

友元的声明只能出现在类定义的内部,具体位置不限,友元不是类的成员,不受类访问控制符的约束

友元函数也可以在类的内部定义,就算在类的内部定义,我们也必须在外提供相应的声明,使得函数可见,上传c++primer中的代码P252

struct X
{
friend void f(){ /* 友元函数可以定义在类的内部 */ }
X(){ f(); }        //错误,f还没声明
void g();
void f();
}
void X::g(){ return f(); }   //错误,f还没声明
void f();                   //声明定义在X中的函数
void X::h(){ return f(); }   //正确,f已经声明在作用域中


可以参考的文章

http://www.cnblogs.com/BeyondAnyTime/archive/2012/06/04/2535305.html

http://zhidao.baidu.com/link?url=q_j0Xn78Fu2JHKZr3S4IPmYiyo2q0-TWOSbUh1oR273X5Sc3r_-3jDqNuLXQfGVCVHxx-xVVo7_-FZhXERmp1PtM9nSs3T6JXai6wSxvg7W
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息