0
点赞
收藏
分享

微信扫一扫

c++ 有元类和有元函数详解及其示例

友元类
    有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员
    友元除了前面讲过的函数以外,友元还可以是类,即一个类可以作另一个类的友元。当一个类作为另一个类的友元时,这就意味着这个类的所有成员函数都是另一个类的友元函数
    友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend,其格式如下:

   friend 类型 函数名(形式参数);

使用友元类时注意:
(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明

总结起来:

(1)友元关系不可以继承,但对已有的方法来说访问权限不改变。
(2)如果改写基类的方法则访问权限改变
(3)友元关系不具有传递性;若类B是类A的友元,类C是B的友元,类C不一定是类A的友元。

友元类的使用:

#include <iostream>  
using namespace std;  
  
class CObj  
{  
public:  
    CObj() : mX(0), mY(0) {}  
    friend class CFriend;  
private:  
    void PrintData() const  
    {  
        cout << "mX = " << mX << endl  
             << "mY = " << mY << endl;  
    }  
    int mX;  
    int mY;  
};  
  
class CFriend  
{  
public:  
    CFriend(int x, int y)  
    {  
        mObj.mX = x;    //直接调用类CObj的私有数据成员  
        mObj.mY = y;  
    }  
    void ShowData() const  
    {  
        mObj.PrintData();   //直接调用类CObj的私有成员函数  
    }  
private:  
    CObj mObj;  
};  
int main()  
{  
    CFriend one(3, 4);  
    one.ShowData();  
    return 0;  
}  

执行结果:

mX = 3
mY = 4

友元函数的使用:

#include <iostream>
#include <string>
using namespace std;

class ca;    //事先申明ca类,确保cb类的定义不出错

class cb {    //在ca类之前定义cb类,确保在ca类里申明cb的test()作友元时不出错
public:
    void test(ca& a);    //由于ca类事先申明,这儿不出错
};

class ca {
    string id;
    void setId(string s) {
        id = s;
    }
protected:
    string name;
    void setName(string s) {
        name = s;
    }
public:
    void print() {
        cout << id << "  " << name << "  " << endl;
    }
    friend void cb::test(ca& a);    //申明cb类的test()函数作友元,允许它访问私有保护成员
};

void cb::test(ca& a) {  //作友元的成员函数的实装必须在ca类的后面,否则ca类的成员就未定义了。
    a.id = "123";        //这是ca类的私有成员
    a.setName("abc");    //这是ca类的保护成员
}
int main ( )
{
    ca a;
    cb b;
    b.test(a);
    a.print();

    return 0;
}

执行结果:

123        abc
举报

相关推荐

0 条评论