精华内容
下载资源
问答
  • 在c++中,经常会定义类。类有一个特点就是数据封装数据...使用友元函数将百分制学生的成绩转换成相应的分数等级。 #include<iostream> using namespace std; #include<iomanip> #include<string.h>

    在c++中,经常会定义类。类有一个特点就是数据封装数据隐藏,也就是该类的私有成员以及保护成员只有通过它的成员才能访问。通过中的友元机制则解决了这一问题。友元既可以是独立的一个非成员函数,也可以是其他类中的成员函数,还可以一个独立的其他类。
    一.非成员函数作为友元函数。
    使用友元函数将百分制学生的成绩转换成相应的分数等级。

    #include<iostream>
    using namespace std;
    #include<iomanip>
    #include<string.h>
    class student{
    	private:
    		char name[20];
    		int score;
    		char level[10];
    		public:
    			student(char na[],int sc);//构造函数
    			friend void trans(student &s);
    			void print()
    			{
    				cout<<setw(10)<<name<<setw(8)<<score<<setw(6)<<level<<endl;
    			}
    		
    }; 
    
    student::student(char na[],int sc)//构造函数 
    {
        strcpy(name,na);
    	score=sc;
    }
    void trans(student &s);
    int main()
    {
    	student stu[]={student("小红",78),student("王华",86),student("李明",98),student("孙强",62)};
    	cout<<"输出结果:"<<endl;
    	cout<<setw(10)<<"姓名"<<setw(8)<<"成绩"<<setw(6)<<"等级"<<endl; 
    	for(int i=0;i<4;i++)
    	{
    		 trans(stu[i]);
    		 stu[i].print();
    	}
    	return 0;
     } 
     void trans(student &s)
     {
     	if(s.score>90)
     	strcpy(s.level,"优");
    	 else if(s.score>=80)
    	 strcpy(s.level,"良");
    	 else if(s.score>=70)
    	 strcpy(s.level,"中");
    	 else if(s.score>=60)
    	 strcpy(s.level,"及格") ;
    	 else
    	 strcpy(s.level,"不及格"); 
     }
     
     
    

    strcpy为字符串复制函数,需定义在头文件 string.h 中。
    注意:
    1.非成员函数作为类的友元函数在类外定义,不能在函数名外加"类名::函数名"
    2.非成员函数作为类的友元函数,没有this指针

    展开全文
  • 友元函数

    2018-09-26 17:16:14
    二、友元函数特点友元函数不是当前类的成员函数,但它可以访问该类的所有成员,包括私有成员、保护成员和公有成员。 友元函数可以定义在类内,也可以定义在类外。 三、友元函数的分类 1、将非成员函数声明...

    对友元函数和友元类进行了一些整理:

    一、关于友元函数的定义:

    友元函数可以是不属于任何类的非成员函数,也可以是另一个类的成员函数。

    二、友元函数的特点:

    友元函数不是当前类的成员函数,但它可以访问该类的所有成员,包括私有成员、保护成员和公有成员。

    友元函数可以定义在类内,也可以定义在类外。

    三、友元函数的分类

    1、将非成员函数声明为友元函数

    #include <iostream>
    using namespace std;
    class Date{
    public:
    Date (int y,int m,int d);
    friend void showDate(Date&);  //声明函数showDate为友元函数
    
    }
    ...
    Void showDate (Date& d)
    {
    ...
    }
    ...
    

    这时友元函数的访问原则是:友元函数不是类的成员函数,所以不能直接访问对象的数据成员,必须通过对象名来访问该对象的数据成员。

    引友元提高了程序的运行效率,实现了类之间的数据共享,方便编程。

    2、将成员函数声明为友元函数

    一个类的成员函数也可以作为另一个类的友元,成为友元成员函数。友元成员函数不仅可以访问自己所在类对象中的私有和公有成员,还可以访问访问friend声明语句所在类对象中的成员。

    #include<iostream>
    using namespace std;
    class Time {
    public:
    ...
    void showDate_Time(Date&);
    ...
    
    }
    class Date{
    public:
    Date(int y,int m, int d)
    ...
    friend void Time :: showDate_Time (Date&);
    }
    
    void Time::showDate_Time (Date& d)
    {
    
    }
    //友元函数,函数showDate_Time 可以访问Date类对象中的私有成员数据
    //成员函数,函数showDate_Time 可以访问Time类对象中的私有数据

    四、友元类

    定义:将一个类定义为也可以定义为友元类

    如:在X类中加入friend Y类,则这时的Y类就是X类的友元类

    这意味着Y类中的所有函数都可以访问X类中的所有成员(包括私有成员)

    注意:(1)友元关系是单向的,不具有交换性。如声明了类X是类Y的友元,不等于类Y一定是X的友元。

    (2)友元不具有传递性,若类X是类Y的友元,类Y是类Z的友元,不一定类X是类Z的友元。必须在类Z中声明。

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

    2021-03-19 20:43:19
    友元函数的一些特点: 1.友元函数需要在类中任意位置进行声明,跟普通函数声明不同的是要加上friend 关键字,然后在类外进行实现,所以友元函数并不是类的成员函数。声明为友元函数之后,友元函数便可访问类中的私有...

    1.友元函数

    友元函数的一些特点:
    1.友元函数需要在类中任意位置进行声明,跟普通函数声明不同的是要加上friend 关键字,然后在类外进行实现,所以友元函数并不是类的成员函数。声明为友元函数之后,友元函数便可访问类中的私有成员。
    2.友元函数没有隐藏的this指针,故参数列表中要多一个类的参数,相当于this指针,但是不一定为第一个参数,这使得友元函数的操作更加灵活,能够完成一些成员函数无法完成的操作,使用友元函数将会使类的操作更加灵活。
    比如:

    class Complex
    {
    public:
    	Complex(int real = 0, int imag = 0) :m_real(real), m_imag(imag)
    	{}
    	~Complex()
    	{}
    	Complex operator+(int  a) {
    		return Complex(m_real + a, m_imag);
    	}
    private:
    	int m_real;
    	int m_imag;
    };
    
    void main()
    {
    	Complex c, c1(1, 3);
    	c = c1 + 10;
    	//c = 10 + c1;  
    }
    

    这里我们通过运算符重载+号实现了Complex + int 即c = c1 + 10; ,编译器可以运行通过;
    但是如果想实现int +Complex 即//c = 10 + c1; 的话,还是需要对+号进行运算符重载,重新解释+号的含义,但是由于类中的成员函数第一个参数默认为自身类型this,按照c = 10 + c1这样赋值运算的话,相当于调动10.operator(c1),10并不是一个对象,无法给Complex operator+(int a)函数中的this指针传参,无法编译通过。
    那么如何解决上面的问题呢?这就需要用友元函数来实现了:

    
    class Complex
    {
    	friend Complex operator+(int val, const Complex& c);  //将函数声明为友元函数,加friend关键字
    	friend Complex operator+(const Complex& c1, const Complex& c2);
    public:
    	Complex(int real = 0, int imag = 0) :m_real(real), m_imag(imag)
    	{}
    	Complex& operator=(const Complex& c)
    	{
    		if (this != &c)
    		{
    			m_real = c.m_real;
    			m_imag = c.m_imag;
    		}
    		return *this;
    	}
    	~Complex()
    	{}
    	Complex operator+(int  a) {
    		return Complex(m_real + a, m_imag);
    	}
    private:
    	int m_real;
    	int m_imag;
    };
    
    Complex operator+(int val, const Complex& c)
    {
    	return Complex(val + c.m_real, c.m_imag);   //友元函数可以访问到类中的私有成员。
    }
    
    Complex operator+(const Complex& c1, const Complex& c2)
    {
    	return Complex(c1.m_real + c2.m_real, c1.m_imag + c2.m_imag);
    }
    
    void main()
    {
    	Complex c, c1(1, 3), c2(2, 5);
    	c = c1 + 10;
    	c = 10 + c1;
    	c = c1 + c2;
    }
    

    在这里插入图片描述
    3.友元函数和static成员函数都没有this指针,static成员函数调动的优先级会比友元函数高。
    4.友元函数不能用const修饰,友元函数的调用与普通函数的调用和原理相同。
    5.一个函数可以是多个类的友元函数

    class Stu;   //前向声明
    class Test;
    
    class Test
    {
    	friend void fun(const Test &t, const Stu &s);
    public:
    	Test()
    	{
    	}
    private:
    	int m_a = 0;  //默认值
    	int m_b = 0;
    };
    class Stu
    {
    	friend void fun(const Test &t, const Stu &s);
    public:
    	int m_x = 0;
    	int m_y = 0;;
    };
     void fun(const Test &t, const Stu &s)  //fun()既是class Test也是class Stu的友元函数
    {}
    void main()
    {
    	Test t;
    }
    

    2.友元类

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

    特点:
    1.友元关系是单向的,不具有交换性。
    比如下面的例子有Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。
    2.友元关系不能传递
    如果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)
    		,_t(9,30,45)
    	{}
    	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;
    };
    
    void main()
    {
    	Time t1(11,2,3);
    	Date d1(2020,3,15);
    	Date d2 = d1;
    	d1.SetTimeOfDate(1, 10, 11);
    }
    
    
    

    运行结果

    展开全文
  • 模板类的友元函数

    2015-09-21 16:22:00
    非模板友元函数 模板类的非模板友元函数是说该模板类的友元函数只是一个... 这一类友元函数特点是不带有参数列表,例如:friend void Fn()。这类友元函数通常可以用于全局对象的访问。 #include <iostream...

    非模板友元函数


           模板类非模板友元函数是说该模板类的友元函数只是一个普通函数,并且该函数是非模板函数或该函数不视为模板函数。这里包含了两种情况,下面分别就两个例子进行说明。

    • 函数是非模板函数

           这一类友元函数特点是不带有参数列表,例如:friend void Fn()。这类友元函数通常可以用于全局对象的访问

    #include <iostream>
    using namespace std;
    
    template <class T>
    class MyNumber
    {
    private:
        T m_number;
    
    public:
        MyNumber(T number) : m_number(number) {}
        ~MyNumber() {}
    
    public:
        friend void PrintGlobalNumber();
    };
    
    MyNumber<int> g_GlobalNumber(1);
    
    void PrintGlobalNumber()
    {
        cout << "Global Number is : " << g_GlobalNumber.m_number << endl;
    }
    
    
    int main()
    {
        PrintGlobalNumber();
        return 1;
    }

    • 函数不视为模板函数

           这类友元函数通常带有参数,并且参数中含有模板类定义的类型变量,例如:friend void Fn(MyClass<T> &n)。由于我们不将该函数视为模板函数,因此对模板类的每个实例化版本都需要提供该函数的一个重载版本

           需要注意,这种用法g++编译器将会给出警告:warning: friend declaration ‘xxxx’ declares a non-template function [-Wnon-template-friend]。关闭该警告方法是加入选项-Wno-non-template-friend,例如:g++ -Wno-non-template-friend -o test test.cpp

    #include <iostream>
    using namespace std;
    
    template <class T>
    class MyNumber
    {
    private:
        T m_number;
    
    public:
        MyNumber(T number) : m_number(number) {}
        ~MyNumber() {}
    
    public:
        friend void PrintNumber(MyNumber<T> &number);
    };
    
    void PrintNumber(MyNumber<int> &number)
    {
        cout << "Int Number is : " << number.m_number << endl;
    }
    
    void PrintNumber(MyNumber<float> &number)
    {
        cout << "Float Number is : " << number.m_number << endl;
    }
    
    int main()
    {
        MyNumber<int>   n0(1   );
        MyNumber<float> n1(2.0f);
        PrintNumber(n0);
        PrintNumber(n1);
    
        return 1;
    }

     模板类的约束模板友元函数


           如果使用上面第二种方法来定义友元函数,那么局限性非常大:每当增加一个模板类的具体实例,就要相对应提供友元函数的一个重载版本。最好的办法就是应该将友元函数使用模板来实现。这里所谓的约束模板友元,指的是模板友元函数实例化取决于模板类被实例化时的类型

    • T(function) = T(class)

           这种写法是保持模板友元函数的参数类型和模板类的参数类型一致。可以将友元函数的声明和定义分开,也可以直接在模板类内部直接定义友元函数。需要注意两种实现写法上的不同。

     ▶ 友元函数声明和定义分开

    #include <iostream>
    using namespace std;
    
    // declare template function, T(function) = T(class)
    template <class T> class MyNumber;                        
    template <class T> void PrintNumber(MyNumber<T> &number); 
    
    template <class T>
    class MyNumber
    {
    private:
        T m_number;
    
    public:
        MyNumber(T number) : m_number(number) {}
        ~MyNumber() {}
    
    public:
        // declare friend function                            
        friend void PrintNumber<T>(MyNumber<T> &number);      
    };
    // function definition template <class T> void PrintNumber(MyNumber<T> &number) { cout << "The Number is : " << number.m_number << endl; } int main() { MyNumber<int> n0(1 ); MyNumber<float> n1(2.0f); PrintNumber(n0); PrintNumber(n1); return 1; }

     ▶ 友元函数直接定义在模板类内部

    #include <iostream>
    using namespace std;
    
    template <class T>
    class MyNumber
    {
    private:
        T m_number;
    
    public:
        MyNumber(T number) : m_number(number) {}
        ~MyNumber() {}
    
    public:
        friend void PrintNumber(MyNumber<T> &number)              
        {                                                         
            cout << "The Number is : " << number.m_number << endl;
        }                                                         
    };
    
    int main()
    {
        MyNumber<int>   n0(1);
        MyNumber<float> n1(2.0f);
        PrintNumber(n0);
        PrintNumber(n1);
    
        return 1;
    }

     • T(function) = class<T>

          这种写法是让模板友元函数的参数类型和模板类类型一致。

    #include <iostream>
    using namespace std;
    
    // declare template function, T(function) = class<T>
    template <class T> void PrintNumber(T &number);
    
    template <class T>
    class MyNumber
    {
    private:
        T m_number;
    
    public:
        MyNumber(T number) : m_number(number) {}
        ~MyNumber() {}
    
    public:
        // declare friend function
        friend void PrintNumber<MyNumber<T> >(MyNumber<T> &number);
    };
    
    // function definition
    template <class T>
    void PrintNumber(T &number)
    {
        cout << "The Number is : " << number.m_number << endl;
    }
    
    int main()
    {
        MyNumber<int>   n0(1   );
        MyNumber<float> n1(2.0f);
        PrintNumber(n0);
        PrintNumber(n1);
    
        return 1;
    }

     模板类的非约束模板友元函数


           这里所谓的约束模板友元,指的是友元函数的所有实例化版本都是模板类的每一个实例化版本的友元。

    • T(function) = T(class)

           这种写法是保持模板友元函数的参数类型和模板类的参数类型一致。

    #include <iostream>
    using namespace std;
    
    template <class T>
    class MyNumber
    {
    private:
        T m_number;
    
    public:
        MyNumber(T number) : m_number(number) {}
        ~MyNumber() {}
    
    public:
        template <class D>
        friend void PrintNumber(MyNumber<D> &number);
    };
    
    template <class T>
    void PrintNumber(MyNumber<T> &number)
    {
        cout << "The Number is : " << number.m_number << endl;
    }
    
    int main()
    {
        MyNumber<int>   n0(1);
        MyNumber<float> n1(2.0f);
        PrintNumber(n0);
        PrintNumber(n1);
    
        return 1;
    }

      • T(function) = class<T>

          这种写法是让模板友元函数的参数类型和模板类类型一致。

    #include <iostream>
    using namespace std;
    
    template <class T>
    class MyNumber
    {
    private:
        T m_number;
    
    public:
        MyNumber(T number) : m_number(number) {}
        ~MyNumber() {}
    
    public:
        template <class D>
        friend void PrintNumber(D &number);
    };
    
    template <class T>
    void PrintNumber(T &number)
    {
        cout << "The Number is : " << number.m_number << endl;
    }
    
    int main()
    {
        MyNumber<int>   n0(1);
        MyNumber<float> n1(2.0f);
        PrintNumber(n0);
        PrintNumber(n1);
    
        return 1;
    }

     

    转载于:https://www.cnblogs.com/heartchord/p/4822422.html

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

    2017-05-14 09:55:07
    友元函数: 将普通函数声明为类的好朋友friend。...//友元函数特点是:有一个参数是友元类的指针或引用 friend int OpMem(Test2 *p, int a); //友元函数 Test2(int a, int b) { this->a = a; th
  • C++类的友元函数

    2019-02-27 14:56:49
    友元函数是类的辅助手段,友元能够引用类中本来被隐蔽的信息。 使用友元的目的是基于程序的运行效率。 一般运算符重载和两个类共享数据这两个场合需要使用友元。 友元可以是函数,也可以是类,...
  • 友元函数特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
  • 【C++】友元函数

    2021-02-21 20:16:06
    友元函数 特点: 单方向 不具有传递性 不具有继承特性 1.(外部)函数友元 注意:主函数也是外部函数 Windows支持多线程,线程是调度单位,进程是资源单位 Linux有两种调度单位,进程、线程 class Int { private: ...
  • 一、友元函数 1.1 友元函数的定义 ...1.2 友元函数特点 友元函数破坏了类的私有性 友元函数是一个全局函数 友元函数形式:一般情况下都包含类的指针或引用 友元函数在public之下或者是private下都无...
  • 友元函数用法

    千次阅读 2012-09-04 17:43:08
     友元函数特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样。下面举一例子说明友元函数的应用。  #include  #include  class ...
  • 友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类...友元函数特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
  • 友元函数和友元类

    2016-03-21 10:41:56
    1.友元函数特点很明显: 有一个参数是友元类的指针或引用。友元函数的使用步骤: 1>在友元类中声明,关键字friend,必有一个参数为友元类的指针或引用。 2>在外部定义 3>在其他地方使用。class Test2 { public...
  • 友元函数(c++)

    2020-03-29 19:37:36
    定义:利用有元机制,允许类中私有数据的访问权限赋予一个类(友元类)或一个函数(友元函数)。 表示: friend 函数类型 友元函数名(参数){ XXXXXXXXXXXXXXX } 特点: 1.可以在类中各个地方,不受public,...
  • 友元函数 友元函数特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样。下面举一例子说明友元函数的应用。 #include #include class Point { ...
  • 友元函数:如果一个函数func(),它是类A的友元函数,该函数可以通过A的对象使用A所有成员(包括私有成员)定义方式:1.在类中写出函数声明2.在函数声明前加一个关键字 friend特点:1.友元函数不是类的内部函数,是...
  • 非成员友元函数、成员友元函数和友元类 1、友元的作用: (1)友元提供了不同类的成员函数之间、类的成员函数与一般函数之间进行了数据共享的机制; 2、友元的优点和缺点 优点:提高程序的运行效率; 缺点:...
  • 友元函数特点是,可以与成员函数一样具有访问private 成员变量。但友元函数并不是成员函数。 创建友元函数的关键在于,将其原型放在类声明中,并在函数名前加上关键字friend。 #include using namespace ...
  • c++ 友元函数友元类

    2015-04-13 20:35:14
    #include using namespace std; //const c 冒牌货 //register cpu 身边的小... //有元函数 特点:有一个参数是友元类的指针或引用 friend int opNum(Test2* p,int a);//函数声明 也可以放到protected ,private 中
  • 如果一个函数 func(), 它是类A 的友元函数,该函数可以通过A的对象使用A 的所有成员(包括私有成员)// 定义方式:// 1、在类中写出函数声明// 2、在函数声明前加一个关键字 friend// 特点:// 1、友元函数不是类的...
  • 面试的时候面试官问到了友元函数,自己其实之前对友元函数不是特别熟悉,只是略知一二;当然,回答的不是很让面试官满意,今天总体的再学习一下友元函数。 1.什么是友元函数特点: ①在类中声明的以friend关键字...

空空如也

空空如也

1 2 3 4 5 ... 16
收藏数 317
精华内容 126
关键字:

友元函数特点