温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C++中友元是什么意思

发布时间:2022-03-08 14:45:39 来源:亿速云 阅读:145 作者:小新 栏目:开发技术

这篇文章将为大家详细讲解有关C++中友元是什么意思,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

    一.友元函数

    友元函数可以是普通函数或者类成员函数。

    先看普通函数声明为友元函数:

    如下所示:

    #include <iostream>
    #include <cmath>
    using namespace std;
    class Point
    {
        //普通函数声明为类的友元函数
    	friend double TwoPointsDistant(const Point& pnt1, const Point& pnt2);
    public:
    	Point(double x=0, double y=0)
    		:_x(x), _y(y)
    	{}
    	double getPointXAxis() const { return this->_x; }
    	double getPointYAxis() const { return this->_y; }
    private:
    	double _x;
    	double _y;
    };
    //计算两点的距离
    double TwoPointsDistant(const Point& pnt1, const Point& pnt2)
    {
    	return sqrt(  pow((pnt1._x - pnt2._x), 2) + pow((pnt1._y - pnt2._y), 2)   );
    }
    int main()
    {
    	Point point1(1.1,2.2);
    	Point point2(3.3, 4.4);
    	cout << TwoPointsDistant(point1, point2) << endl;
    	system("pause");
    	return 0;
    }

    这里说明一点:TwoPointsDistant()函数必须在Point类的定义下面,至于原因,很简单,你若放在Point上面,Point的数据成员_x和_y都没定义呢,你用个锤子。

    再看类成员函数声明为友元函数:

    还以上面的类为例,现在加一个_PointMove_类,它有一个成员函数_PointAxisAddOne,_作用是将点的坐标都加1。如下:

    class PointMove
    {
    public:
    	void PointAxisAddOne(Point& pnt);
    };

    这里就出现了一个问题:_Point_和_PointMove_哪个放在前面?先给出答案,应该把_PointMove_放在前面,并且是必须的,如下:

    class Point;//前向声明Point
    class PointMove
    {
    public:
    	void PointAxisAddOne(Point& pnt);
    };
    class Point
    {
        //普通函数声明为类的友元函数
    	friend double TwoPointsDistant(const Point& pnt1, const Point& pnt2);
        //类成员函数声明为友元
    	friend void PointMove::PointAxisAddOne(Point& pnt);
        /*这里同前*/
    };
    //类成员函数的定义
    void PointMove::PointAxisAddOne(Point& pnt)
    {
    	pnt._x = pnt._x + 1;
    	pnt._y = pnt._y + 1;
    }

    这里注意,对于类的成员函数,声明为其他类的友元函数时需要加上类的作用域,即指出该函数属于哪个类。如上面的_PointMove::_。

    同时,需要说明的是,PointAxisAddOne()函数的定义是必须放在Point类定义后面的,这和普通函数的道理是一样的。

    最后说明

    1.一个函数Func被声明为类A的友元函数,那么是不能直接使用this指针来访问类A的数据成员的(当然,若Func是类B的成员函数,它可以通过this访问类B的数据成员),这和成员函数不同。

    2.一个函数Func为什么要声明为某个类A的友元,就是因为函数的参数类型为类A类型,我想访问这个类对象的数据成员,所以被声明为类A的友元函数的参数类型必定为类A,如friend Func(A& obj);

    二.友元类

    若是将一个类C都声明为另一个类A的友元类,则类C中的成员函数均可访问类A中的私有数据成员。如下:

    class Point
    {
        //友元类
        friend class PointInfo;
        ...
    }
    class PointInfo
    {
    public:
    	//打印点所处象限
    	void PrintQuadrant(const Point& pnt) const
    	{
    		if (pnt._x > 0 && pnt._y > 0)
    			cout << "点"<<"(" << pnt._x << "," << pnt._y<<")" <<"处于第一象限" << endl;
    	}
    };

    当然,你也可以把_PointInfo_写在_Point_前,只是函数_PrintQuadrant()_的定义就不能在类内实现了,只能在_Point_后实现,原因和前面一样,不再赘述。

    三.完整示例:

    #include <iostream>
    #include <cmath>
    using namespace std;
    class Point;
    class PointMove
    {
    public:
    	void PointAxisAddOne(Point& pnt);
    };
    class PointInfo
    {
    public:
    	//打印点所处象限
    	void PrintQuadrant(const Point& pnt) const;
    };
    class Point
    {
    	friend class PointInfo;
    	friend double TwoPointsDistant(const Point& pnt1, const Point& pnt2);
    	friend void PointMove::PointAxisAddOne(Point& pnt);
    public:
    	Point(double x=0, double y=0)
    		:_x(x), _y(y)
    	{}
    	double getPointXAxis() const { return this->_x; }
    	double getPointYAxis() const { return this->_y; }
    	void PrintAxis(const Point& pnt) const
    	{
    	}
    private:
    	double _x;
    	double _y;
    };
    //打印点所处象限
    void PointInfo::PrintQuadrant(const Point& pnt) const
    {
    	if (pnt._x > 0 && pnt._y > 0)
    	cout << "点"<<"(" << pnt._x << "," << pnt._y<<")" <<"处于第一象限" << endl;
    }
    void PointMove::PointAxisAddOne(Point& pnt)
    {
    	pnt._x = pnt._x + 1;
    	pnt._y = pnt._y + 1;
    }
    double TwoPointsDistant(const Point& pnt1, const Point& pnt2)
    {
    	return sqrt(  pow((pnt1._x - pnt2._x), 2) + pow((pnt1._y - pnt2._y), 2)   );
    }
    int main()
    {
    	Point point1(1.1,2.2);
    	Point point2(3.3, 4.4);
    	cout << TwoPointsDistant(point1, point2) << endl;
    	PointInfo pf;
    	pf.PrintQuadrant(point1);
    	system("pause");
    	return 0;
    }

    VS2015打印结果:

    C++中友元是什么意思

    四.同一个类(class)的类对象(object)互为友元

    还以上面给出的例子为基础,现在在_Point_类加一个成员函数func(const Point& pnt),它返回点的x轴和y轴的和。如下所示。

    class Point
    {
        /*这里同上*/
    	double func(const Point& pnt)
    	{
    		return pnt._x + pnt._y;
    	}
    private:
    	double _x;
    	double _y;
    };

    现在我生成两个对象,并作如下操作:

    	Point point1(1.1,2.2);
    	Point point2(3.3, 4.4);
    	cout << point1.func(point2) << endl;

    最后的结果是打印出7.7。看到这里不知道你有没有疑问:为什么可以通过point1直接访问point2的私有数据成员,而没有将func()声明为友元函数?侯捷老师是这么解释的:相同class的各个objects之间互为友元。

    所以对于一个类A,若有一个成员函数Fun(A& arg),可以通过arg直接访问A的私有数据成员。

    关于“C++中友元是什么意思”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    c++
    AI