精华内容
下载资源
问答
  • 其实友元确实不是很常用,但友元功能确实很实用,它不但能够释放中的非公有成员,同时还能保证了的封装性。用户可以有选择为具体的或函数赋予“通行证”。还是比较灵活的。比如:某个去访问另一个的私有成...

    学习了c++这么久,一直没有对友元进行了解,据说友元不是特别好用(据说,不是我说的),因此直到今天才去了解。其实友元确实不是很常用,但友元功能确实很实用,它不但能够释放类中的非公有成员,同时还能保证了类的封装性。用户可以有选择为具体的类或函数赋予“通行证”。还是比较灵活的。比如:某个类去访问另一个类的私有成成员,或者一个函数去访问某个类的私有成员等等,都可以使用友元来实现。

    下面就友元做了两个小例子,望高手指教。(每段代码都在不同的文件中)

    首先是关于友元类的代码,就一句话,很简单。。。

    Test.h:

    #ifndef TEST_H

    #define TEST_H

    #include

    using namespace std;

    class Test

    {

    friend class FriendTest; //此处声明FriendTest为Test的友元类,FriendTest类可以访问Test的私有成员

    public:

    Test();

    void set(int h,int w);

    void print();

    virtual ~Test();

    protected:

    private:

    int height;

    int weight;

    };

    #endif // TEST_H

    Test.cpp

    #include "../include/Test.h"

    Test::Test()

    {

    //ctor

    height = 0;

    weight = 0;

    }

    void Test::set(int h, int w)

    {

    height = h;

    weight = w;

    }

    void Test::print()

    {

    cout << height << " ";

    cout << weight <

    }

    Test::~Test()

    {

    //dtor

    }

    下面关于FriendTest的相关程序。

    FriendTest.h

    #ifndef FRIENDTEST_H

    #define FRIENDTEST_H

    #include "Test.h"

    class FriendTest

    {

    public:

    FriendTest();

    void setTest(Test& t, int h, int w);

    virtual ~FriendTest();

    protected:

    private:

    };

    #endif // FRIENDTEST_H

    FriendTest.cpp

    #include "../include/FriendTest.h"

    FriendTest::FriendTest()

    {

    //ctor

    }

    void FriendTest::setTest(Test& t, int h, int w) //之前声明了友元,所以此处可以调用私有成员

    {

    t.height = h;

    t.weight = w;

    }

    FriendTest::~FriendTest()

    {

    //dtor

    }#include

    #include "./include/Test.h"

    #include "./include/FriendTest.h"

    using namespace std;

    int main()

    {

    Test t;

    FriendTest ft;

    t.set(30, 20);

    ft.setTest(t,9,8);

    t.print();

    return 0;

    }

    接下来是关于友元函数的问题,友元函数我弄了很久,对于某个类来说,只希望其某个函数为友元,需要对函数进行友元声明。然而将上边代码中的友元类的声明改成友元函数的声明,编译不通过,提示未定义。后来发现对于友元函数来说两个类必须放在同一个文件中,并且要有部分调整,具体实现如下,并富有详解。

    部分代码省略。。。主要代码如下:

    #include

    using namespace std;

    //由于两个类都使用到了另一个类,所以顺序很关键。如果将两个类的顺序颠倒会出现编译不通过,并提示未定义。另外友元函数必须在最后实现,因为它用到了两个类中的成员。仔细与上一部分的代码比较,你便会了解里边的玄机。。。

    class Test; //首先需要声明Test类,FriendTest类中需要使用。

    class FriendTest

    {

    public:

    FriendTest();

    void setTest(Test& t, int h, int w);

    virtual ~FriendTest();

    protected:

    private:

    };

    class Test

    {

    friend void FriendTest::setTest(Test& t, int h, int w); //友元函数声明

    public:

    Test();

    void set(int h,int w);

    void print();

    virtual ~Test();

    protected:

    private:

    int height;

    int weight;

    };

    void FriendTest::setTest(Test& t, int h, int w)

    {

    t.height = h;

    t.weight = w;

    }

    int main()

    {

    cout << "friend" <

    Test t;

    FriendTest ft;

    t.set(30, 20);

    ft.setTest(t,9,8);

    t.print();

    return 0;

    }

    另外在网上看到了一个关于primer c++中一个友元例子的讲解可能对你理解有些帮助:

    做了部分修改。。。。。。

    第一种写法问题:

    编译到Screen时,由于Screen类使用到Window_Mgr的成员函数,前面给出了Window_Mgr的声明,但不清楚Window_Mgr的完整定义,对成员函数不清楚,所以友元函数声明不成立,编译出错。

    class Window_Mgr

    class Screen

    {

    public:

    friend Window_Mgr& Window_Mgr::relocate(Window_Mgr::index r, Window_Mgr::index c, Screen& s);

    private:

    int height;

    int width;

    }

    class Window_Mgr

    {

    public:

    typedef std::string::size_type index;

    Window_Mgr& Window_Mgr::relocate(index r, index c, Screen& s)

    {

    s.height += r;

    s.width += c;

    return *this;

    }

    }

    第二种写法问题在于:

    编译到relocate时,由于Screen& s的实现使用到Screen的成员变量,虽然前面给出了Screen的声明,但此时还不清楚Screen的完整定义,所以编译出错。

    class Screen;

    class Window_Mgr

    {

    public:

    typedef std::string::size_type index;

    Window_Mgr& Window_Mgr::relocate(index r, index c, Screen& s)

    {

    s.height += r;

    s.width += c;

    return *this;

    }

    }

    class Screen

    {

    public:

    friend Window_Mgr& Window_Mgr::relocate(Window_Mgr::index r, Window_Mgr::index c, Screen& s);

    private:

    int height;

    int width;

    }

    第三种写法:

    将Window_Mgr::relocate的实现移动到最后,由于编译类Window_Mgr时,并不需要Screen&s 的实现细节,问题得到解决

    class Screen;

    class Window_Mgr

    {

    public:

    typedef std::string::size_type index;

    Window_Mgr& Window_Mgr::relocate(index r, index c, Screen& s);   //无内部成员的使用

    }

    class Screen

    {

    public:

    friend Window_Mgr& Window_Mgr::relocate(Window_Mgr::index r, Window_Mgr::index c, Screen& s);

    private:

    int height;

    int width;

    }

    Window_Mgr& Window_Mgr::relocate(Window_Mgr::index r, Window_Mgr::index c, Screen& s)

    {

    s.height += r;

    s.width += c;

    return *this;

    }

    可见,这两个类如果编译成功需要严格的交替顺序

    这也就解释了为什么放在两个文件中无法编译。

    附录:

    一开始的实现的不能编译的两个文件

    实现分别如下:Window_Mgr.h

    #ifndef WINDOW_MGR //为了避免两个文件嵌套

    #define WINDOW_MGR

    #include

    #include

    class Window_Mgr

    {

    public:

    typedef std::string::size_type index;

    Window_Mgr& Window_Mgr::relocate(index r, index c, Screen& s)

    {

    s.height += r;

    s.width += c;

    return *this;

    }

    }

    #endif

    Screen.h

    #ifndef SCREEN

    #define SCREEN

    #include "Window_Mgr.h"

    class Screen

    {

    public:

    friend Window_Mgr& Window_Mgr::relocate(Window_Mgr::index r, Window_Mgr::index c, Screen& s);

    private:

    int height;

    int width;

    }

    #endif

    展开全文
  • 友元函数和友元类

    2021-05-26 22:40:49
    友元有:友元函数,友元成员,友元类 友元可以放在类的公有,私有,保护部分。 友元函数 1.友元函数可访问类的私有和保护成员,但不是类的成员函数 2.友元函数不能用const修饰 3.友元函数可以在类定义的任何地方...

    友元的概念:
    遵循一定规则而使对象以外的软件系统能够不经过消息方式而直接访对象内封装的数据成员的技术方法便是友元。
    友元是面向对象系统与过程系统衔接纽带。

    友元有:友元函数,友元成员,友元类
    友元可以放在类的公有,私有,保护部分。

    友元函数

    1.友元函数可访问类的私有和保护成员,但不是类的成员函数
    2.友元函数不能用const修饰
    3.友元函数可以在类定义的任何地方声明,不受类访问限定符限制
    4.一个函数可以是多个类的友元函数

    在类的定义中用friend声明了一个外部函数或其他类的成员函数(publicprivate均可)后,这个外部函数称为类的友元函数。
    

    由干友元函数不是类的成员,所以没有this指针,访问该类的对象的成员时,必须使用对象名,而不能直接使用类的成员名。
    虽然友元函数是在类中说明的,但其名字的作用域在类外,作用域的开始点在说明点、结束点和类名相同。因此,友元说明可以代替该函数的函数说明。

    #include <bits/stdc++.h>
    using namespace std;
    
    class Point {
    	private:
    		int x, y;
    		friend float dis(Point &p1, Point &p2);
    		//可以是public,也可是private
    
    	public:
    		Point(int i, int j) {	//构造函数,带缺省参数值
    			x = i;
    			y = j;
    		}
    
    		void disp() {	
    			cout << "(" << x << "," << y << ")";
    		}
    };
    
    float dis(Point &p1, Point &p2) {	//友元函数的实现
    	//友元函数中可访问类的private成员
    	float d = sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
    	return d;
    }
    
    int main() {
    	Point p1(1, 2), p2(4, 5);	//声明两个Point类的对象p1和p2
    	p1.disp();			//显示点p1的信息
    
    	cout << "与";
    	p2.disp();			//显示点p2的信息
    
    	cout << "距离=" << dis(p1, p2) << endl;	//利用友元函数计算两点举例
    
    	return 0;
    }
    
    

    友元类

    友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
    友元关系是单向的,不具有交换性。
    友元关系不能传递->如果B是A的友元,C是B的友元,则不能说明C时A的友元。

    class Date; // 前置声明
    class Time
    {
     friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成
    员变量
    public:
     Time(int hour, int minute, int second):_hour(hour) , _minute(minute) , _second(second)
     {}
     
    private:
     int _hour;
     int _minute;
     int _second;
    };
    class Date
    {
    public:
     Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month) , _day(day)
     {}
     
     void SetTimeOfDate(int hour, int minute, int second)
     {
     // 直接访问时间类私有的成员变量
     _t._hour = hour;
     _t._minute = minute;
     _t.second = second;
     }
     
    private:
     int _year;
     int _month;
     int _day;
     Time _t;
    };
    
    
    #include <iostream>
    
    using namespace std;
    
    class Box
    {
        double width;
    public:
        friend void printWidth(Box box);
        friend class BigBox;
        void setWidth(double wid);
    };
    
    class BigBox
    {
    public :
        void Print(int width, Box &box)
        {
            // BigBox是Box的友元类,它可以直接访问Box类的任何成员
            box.setWidth(width);
            cout << "Width of box : " << box.width << endl;
        }
    };
    
    // 成员函数定义
    void Box::setWidth(double wid)
    {
        width = wid;
    }
    
    // 请注意:printWidth() 不是任何类的成员函数
    void printWidth(Box box)
    {
        /* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */
        cout << "Width of box : " << box.width << endl;
    }
    
    // 程序的主函数
    int main()
    {
        Box box;
        BigBox big;
    
        // 使用成员函数设置宽度
        box.setWidth(10.0);
    
        // 使用友元函数输出宽度
        printWidth(box);
    
        // 使用友元类中的方法设置宽度
        big.Print(20, box);
    
        getchar();
        return 0;
    }
    
    

    友元成员
    除了一般的函数可以作为某个类的友元外,另一个类的成员函数也可以作为某个类的友元。声明时需在友元成员函数前加上其所在的类名。定义友元成员的好处是两个类可以以某种方式相互合作、协调工作,完成某一任务。

    另一个类的成员函数可以作为某个类的友元,只是声名友元函数时要加上成员函数所在的类名,称为友元成员。
    声名:
    friend 函数返回类型 类名::成员函数名(形参列表)

    #include <iostream>
    using namespace std;
    class date;
    
    class time 
    {
    	public:
    		time(int, int, int);
    		void display(date &);
    	private:
    		int hour;
    		int minute;
    		int sec;
    };
    
    class date 
    {
    	public:
    		date(int, int, int);
    		friend void time::display(date &);
    	private:
    		int month;
    		int day;
    		int year;
    };
    
    time::time(int h, int m, int s) 
    {
    	hour = h;
    	minute = m;
    	sec = s;
    }
    
    void time::display(date &d) 
    {
    	cout << d.month << "." << d.day << "." << d.year << endl;
    	cout << hour << ":" << minute << ":" << sec << endl;
    }
    
    date::date(int m, int d, int y) 
    {
    	month = m;
    	day = d;
    	year = y;
    }
    
    int main () 
    {
    	time t1(10, 51, 56);
    	date d1(3, 20, 2018);
    	t1.display(d1);
    	return 0;
    }
    
    展开全文
  • 友元类与内部类

    2021-02-20 19:12:47
    友元分为友元函数和友元类 友元是一种突破了封装的方式,有时候为了方便使用友元类,但是友元破坏了封装性,一般不会多用。 友元函数可以直接访问类的私有成员,它是不属于类的内部,它是类外部的普通函数,不属于...

    友元与内部类

    友元分为友元函数和友元类
    友元是一种突破了封装的方式,有时候为了方便使用友元类,但是友元破坏了封装性,一般不会多用。

    • 友元函数可以直接访问类的私有成员,它是不属于类的内部,它是类外部的普通函数,不属于任何类,但是需要在类内部声明,声明时需要加friend关键字。
    class Date
    {
    	friend ostream& operator<<(ostream& _cout, const Date& d);
    	friend istream& operator>>(istream& _cin, Date& d);
    public:
    	Date()
    	{
    
    	}
    	Date(int year, int month, int day)
    		: _year(year)
    		, _month(month)
    		, _day(day)
    	{}
    private:
    	int _year;
    	int _month;
    	int _day;
    };
    ostream& operator<<(ostream& _cout, const Date& d)
    {
    	_cout << d._year << "-" << d._month << "-" << d._day;
    	return _cout;
    }
    istream& operator>>(istream& _cin, Date& d)
    {
    	_cin >> d._year;
    	_cin >> d._month;
    	_cin >> d._day;
    	return _cin;
    }
    int main()
    {
    	Date d;
    	cin >> d;
    	cout << d << endl;
    	return 0;
    }
    
    • 友元函数不能用const修饰
    • 友元函数可以在类定义的任何地方声明不受访问限定符的限制
    • 一个函数可以是多个类的友元函数
    • 友元函数的调用和普通函数的调用原理相同

    友元类
    友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

    • 友元关系是单向的不具有交换性
    • 友元关系不具有传递性

    内部类

    内部类:如果一个类定义在另一个类的内部,那么这个类叫做内部类,内部类是一个完整独立的类,不能通过外部类去调用内部类,外部类相较于内部类没有任何的优先级,内部类是外部类的友元类,通过内部类可以调用外部类的成员变量,但是外部类不是内部类的友元
    特性:

    • 内部类可以定义在外部类的public、private、protected都是可以的
    • 注意内部类可以直接访问外部类中的static、枚举成员,不需要外部类的对象/类名
    • sizeof(外部类)=外部类,和内部类没有任何关系
    展开全文
  • 一:让模板的某个实例成为友元。 #include <iostream> #include <vector> #include <list> using namespace std; #pragma warning(disable : 4996) template <typename T> class B; //...

    一:让类模板的某个实例成为友元。

    #include <iostream>
    #include <vector>
    #include <list>
    using namespace std;
    #pragma warning(disable : 4996) 
    
    template <typename T> class B; //声明
    template <typename T>
    class A
    {
    	friend class B<int>;  //针对int类型的类B,
    private:
    	int data;
    };
    template <typename T>
    class B
    {
    public:
    	void callfun()
    	{
    		A<int> p;
    		p.data = 10;	
    		cout << p.data << endl;
    	}
    };
    int main()
    {
    	B<int> obj;
    	obj.callfun();
    	return 0;
    }
    

    二:类模板成为友元类模板。

    #include <iostream>
    #include <vector>
    using namespace std;
    #pragma warning(disable : 4996) 
    template <typename T>
    class A
    {
    	template <typename T>
    	friend class B;
    private:
    	int data;
    };
    template <typename T>
    class B
    {
    public:
    	void callfun()
    	{
    		A<int> p;
    		p.data = 10;	
    		cout << p.data << endl;
    	}
    };
    
    int main()
    {
    	B<long> obj;
    	obj.callfun();
    	return 0;
    }
    

    三:让类型模板参数成为友元类,cpp11。

    #include <iostream>
    #include <vector>
    using namespace std;
    #pragma warning(disable : 4996) 
    
    template <typename T>
    class A
    {
    	friend T; //cpp11
    private:
    	int data;
    };
    class B
    {
    public:
    	void call()
    	{
    		A<B> obj;
    		obj.data = 10;
    		cout << obj.data << endl;
    	}
    };
    int main()
    {
    	B b;
    	b.call();
    	return 0;
    }
    
    展开全文
  • C++ 中友元函数与友元类详解总的来说,友元分为两类:友元函数与友元类。友元是针对类而言,它提供了一种非类的成员函数来访问类的非公有成员的一种机制。可以把一个函数指定为某类的友元,这个函数称为这个类的友元...
  • c++友元类和友元函数

    2021-05-06 16:10:28
    友元函数不属于的成员函数,但是友元函数必须在内部定义; 友元函数使用friend关键词声明; 友元函数能够实现之间的数据共享,较少系统开销,提高效率,但是会破坏的封装机制; class FriendFunc { public:...
  • 如何给友元类设置访问权限? 友元类无限制地访问所在类的所有元素 #include<iostream> #include<string> #include<algorithm> usingnamespacestd; classStudent; classPerson { ...
  • 一、友元介绍我们知道,类的成员函数可以访问同类的...友元函数友元类二、友元函数友元函数在类作用域外定义,但它需要在类体中进行说明为了与该类的成员函数加以区别,定义的方式是在类中用关键字friend说明该函数...
  • 私有成员只能在的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过提供的接口(成员函数)间接地进行。这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的麻烦。C++是从结构化...
  • static静态成员变量 在成员变量前加static,该成员称为静态成员变量 static int _count; 在成员函数前加static,该函数称为静态成员函数 static int getCount() { return _count;...//外定义 int A::_count
  • 友元,是一种突破封装的方式,尽量少用 友元函数 需要友元解决的问题: 运用operator<<进行函数重载,需要输出,若把...但是这样的话,又会导致外没办法访问成员,那么这里就需要友元来解决。 把operator<
  • 除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。 友元...
  • 主要介绍C++中的友元函数和友元类。 二、友元函数 1.介绍 友元函数定义在类的外部,通过友元函数可以在类的外部修改类的私有属性,可理解为该函数是类的好朋友。类中,声明友元函数的关键字为friend,声明的位置...
  • 若按照环境问题的性质分类,属于________ 北师大版八年级下册数学课本第121页练习答案 现有一组物质:海水,盐酸,酒精溶液,下列物质中跟它同一的是()A.冰水B.泥水C.碘酒D.牛奶 小明体检的血液化验单中,...
  • C++之友元类

    2021-08-31 11:10:09
    在类定义中声明友元类的写法如下: friend class 类名; 友元类B类的所有成员函数,都能访问A类对象的私有成员; 类 A 将类 B 声明为友元类,则类 B 最好从逻辑上和类 A 有比较接近的关系。例如上面的例子,C...
  • 友元包括友元函数、友元类和友元成员函数。常用的是友元函数。 友元函数的使用 因为友元函数没有this指针,则参数要有三种情况: 要访问非static成员时,需要对象做参数; 要访问static成员或全局变量时,则不...
  • 1)友元函数是个函数,只要让普通函数func声明为A的友元函数,那么func这个函数就能访问A的所有成员(成员变量、成员函数),无论是public,private,protected 2)由于友元函数不属于成员,所以友元函数的...
  • c++友元函数和友元类

    2021-04-19 14:19:39
    一个外部函数成为友元后,访问权限被扩展了,等同于的内部成员函数了 友元函数是单向的,反过来是不行的 友元函数就好像在的封装和访问权限保护上打了个“洞”,所以是对面向对象的一种破坏,所以不能...
  • C++入门:友元友元提出背景友元函数友元函数特性1-5友元类友元类特性1-2 友元 友元分为:友元函数和友元类 友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。 ...
  • 为什么要使用友元,友元类

    多人点赞 2021-05-22 21:11:10
    这里写目录标题为什么要使用友元友元的两种使用形式友元类使用注意 为什么要使用友元 C++是面向对象的,目的之一:封装 封装: 优点之一,就是安全。 缺点:在某些特殊的场合,不是很方便。 华为与IBM 40亿的咨询...
  • 友元类课本例子

    2021-10-06 03:42:57
    //使用这种方式,需要A构造函数是无参数的 a = r; cout 构造完成" ; } B::~B() { cout 析构完成" ; } int main() { B b(2); //A p(1); //B b(p); b.display(); b.set(3); b.display(); return 0; } /* * A构造完成...
  • C++ 友元函数与友元类

    2021-11-15 14:43:39
    友元类 友元成员函数 1、友元函数 通过让函数成为类的友元,可以赋予该函数与类的成员函数相同的权限。下面介绍友元函数 1.1、声明与定义友元函数 将函数的原型声明放到类声明中,并在原型声明前面加上friend...
  • //-- 声明类B是类A的友元类,则B可以访问类A的所有成员了。 friend class B; private: //public: int data; }; class B { public: void callBAF(int i, A& a){ a.data = i; std::cout << "a.data...
  • 之前只知道在C++中和结构体的区别只有默认的防控属性(访问控制)不同,struct是public的,而class是private的。但经过上网查资料才发现,除了这个不同之外,还有很多的知识点需要掌握。下面就听我一一道来~ 1、...
  • 只要在bai两个要声明的中,分du别将该函zhi数声明为友元函数即可。dao C++对友元函数属于几个并没有限制shu,只要在对应中声明为友元,则该函数即为此类的友元函数。 这个代码只是想说不同的可以共用一个...
  • 友元类的使用方法

    2021-08-03 15:22:19
    学习友元函数之后,我们再来看友元类,也是一样的道理和使用方法,如果把一个类A声明为另一个类B的友元类,则类A中的所有成员函数都可以访问B类中的成员。使用方法也一样,在类B中进行声明即可。 还是上一节的程序...
  • 友元函数和友元类的需要:类具有封装和信息隐藏的特性。只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又...
  • 将time类声明为date类的友元类,通过time·类中的display函数引用date类对象的私有数据,输出年月日和时分秒 #include <iostream> using namespace std; class date { public: date(int,int,int); friend ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,373
精华内容 18,949
关键字:

友元类

友情链接: Qt_BarCode-master.zip