精华内容
下载资源
问答
  • 今天在程序时用到了好多静态成员函数,然后突然想到了友元函数,有些思考。 首先,两者都可以读写对象的成员变量。基于此可以认为静态函数和友元函数都具有访问类内部数据的权限。静态函数毫无疑问具有类作用域,...

    C++笔记--关于友元函数和静态成员函数


    今天在写程序时用到了好多静态成员函数,然后突然想到了友元函数,有些思考。

    首先,两者都可以读写对象的成员变量。基于此可以认为静态函数和友元函数都具有访问类内部数据的权限。静态函数毫无疑问具有类作用域,而友元函数本身可能是全局函数、也可能是其他类的成员函数,所以我猜测是不是可以理解为静态函数是友元函数的一种特例。

    接下来,我想验证友元函数是否也可以具有类作用域,所以我打算在类内部定义一个友元函数。

    接着,我百度到了这篇文章:
    https://blog.csdn.net/weixin_34260991/article/details/93819698

    他在类内部定义了两个友元函数,一个无参数、一个以此类对象为参数。结果,调用无参的函数不能通过编译,以此类对象为参数的函数可以通过编译,并且可以正常运行。

    我认为,因为这两个函数定义在类内部,因此不具有全局作用域,编译器在调用函数这一行会自动检索当前作用域下是否有这个函数的声明,两个函数都没有,但是有参数的那个函数,有一个·类对象作为参数,编译器据此到类内部去检查是否有这个函数的声明,然后它成功找到了。

    所以,他一个函数能通过编译,一个不能通过编译的原因就在于编译器是否找到了函数声明。也就是说,这是一个函数作用域的问题。

    我首先尝试以调用静态函数的写法来调用无参函数,结果编译失败。然后我在全局作用域声明此无参函数,然后在main函数中调用,通过编译,并可正常运行。

    #include <iostream>
    using namespace std;
    
    class T
    {
    public:
    	T(){}
    	~T(){}
    
    	//不引入类对象
    	friend void show_hello_no_param()
    	{
    		cout << "show_hello_no_param() of T : Hello world!\n";
    	}
    
    private:
    	//引入类对象
    	friend void show_hello(T t)
    	{
    		cout << "show_hello() of T : Hello world!\n";
    	}
    
    };
    
    void show_hello_no_param();
    
    int main()
    {
    	T t;
    
    	show_hello_no_param();      //编译通过
    
    	T::show_hello_no_param();   //编译不能通过
    
    	show_hello(t);              //编译可以通过
    
    	getchar();
    
    	return 0;
    }
    
    

    虽说问题解决了,但是对于编译器可以根据函数参数到对应类型作用域内查找函数声明的这种按图索骥的能力表示赞叹!(我没有验证以此类型的对象为返回值是否可以,我认为不可以)

    最后,关于我的猜想(友元函数是否也可以具有类作用域)。我认为不可以。

    展开全文
  • 1.友元函数 关键字:friend  特性:一个类的友元函数,可以访问到类中私有成员 ...将一个类的成员函数声明另一个类的友元 3.友元类 定义一个类另一个类的友元类,在Circle类中定义一

    1.友元函数

    关键字:friend  
    特性:一个类的友元函数,可以访问到类中私有成员

    • 推荐使用引用的方法取访问私有成员,更高效
    • 友元的定义写在public下和private下都是正确的,不过为了直观应写在开头

    2.友元成员函数

    将一个类的成员函数声明为另一个类的友元


    3.友元类

    • 定义一个类为另一个类的友元类,在Circle类中定义一个Coordinate的对象,这个对象可以任意访问Coordinate的数据成员和成员函数


    友元使用的注意事项:
    • 友元关系不可传递
    • 友元关系的单向性
    • 友元声明的形式和数量不受限制
    友元只是封装的补充,不是一种很好的语法
    如果前期类设计巧妙,应当避开使用友元,因为友元破坏了封装性,同时也是一种定向暴露信息的思想。
    展开全文
  • 最近在使用友元函数来访问私有成员时,遇到了问题,用一个类成员函数做另一个类的友元函数,但是一直报错,提示定义其中的一个类型,思考良久(思路:既然友元函数在公有访问权限内,就应该可以访问私有数据成员)...

    最近在使用友元函数来访问私有成员时,遇到了问题,用一个类成员函数做另一个类的友元函数,但是一直报错,提示为定义其中的一个类型,思考良久(思路:既然友元函数在公有访问权限内,就应该可以访问私有数据成员),在网上搜了很多的博客,但是都没有明确的答案,还好最后自己解决了问题,下面写一下自己解决问题的过程,根据个人的理解写了一下注释(也不知道理解的对不对),大家如果有明确答案的请给我反馈一下,谢谢!

    #include<iostream>
    using namespace std;
    class test1;//声明标识符
    class test2
    {
    public:
    	int c;
    	void fun(test1&t);//函数的声明
    private:
    	int d;
    };
    void test2::fun(test1&t)//函数的定义(错误的根源)
    {
    	cout << t.a << endl;
    	cout << t.b << endl;
    }
    class test1
    {
    public:
    	int a;
    	friend void test2::fun(test1&t);//友元函数的声明
    private:
    	int b;
    };
    
    int main()
    {
    
    
    }

    以上代码会报错,错误“error C2027: 使用了未定义类型“test1”,明明已经定义了test1类型,而且还提前声明了,为什么会提示未定义呢?就是找不到问题,最后将函数的定义放到最后就解决了问题,代码如下:

    #include<iostream>
    using namespace std;
    class test1;//标识符
    class test2
    {
    public:
    	int c;
    	void fun(test1&t);//函数声明
    private:
    	int d;
    };
    /*void test2::fun(test1&t)//
    {
    	cout << t.a << endl;//此处要知道test1类型的具体内容,
    但是系统并不知道,虽然在上面声明的该类型,
    但是我们不知道具体内容,具体内容在下面才给出,
    所以会报错,提示未定义类型test1(我个人理解是这样的),
    所以将该函数移动到test1类型后面就不报错了,
    (个人理解,仅供参考,不一定正确)
    	cout << t.b << endl;
    }*/
    class test1
    {
    public:
    	int a;
    	friend void test2::fun(test1&t);//友元函数声明
    private:
    	int b;
    };
    void test2::fun(test1&t)//函数定义放在最后(问题解决了)
    {
    	cout << t.a << endl;
    	cout << t.b << endl;//私有成员会提示“无法访问私有成员”,
    这只是编译器的没有识别出来,但是不影响编译,可以通过编译,我们不用理会。
    }
    int main()
    {
    
    
    }

    个人理解都在代码的注释中阐述了,仅仅是个人理解,仅供参考,不一定正确,但是确实解决了问题。(如果有明确的理解,请帮忙反馈一下,谢谢!)

    展开全文
  • 我有一个类Xth,它有一个private成员 damage,现在想用另一个类 Badao的成员函数 use() 来打印这个值;其实这个问题有很简单 清晰的实现方法,比如在Xth中定义一个专门用来获取damage的值的public函数,等等;但是我...
    问题是这样的:
    我有一个类Xth,它有一个private成员 damage,现在想用另一个类 Badao的成员函数 use() 来打印这个值;其实这个问题有很简单
    清晰的实现方法,比如在Xth中定义一个专门用来获取damage的值的public函数,等等;但是我第一个想到的是用友元函数玩一波骚操作
    问题在与,两个类分别写在各自的头文件中,我一开始以为,两者必须要包含对方的头文件,但是这样根本无法通过编译。
    

    引用某大佬在另一个类似问题上的回答:

    • 友元函数显然是可以的,但是你说的头文件相互包含的问题是可以避免的 你在Book类里面声明Manage类的成员函数为友元函数,因此必然要包含Manage类的头文件,而且你最好使用提前声明,加一句class Manage;
      你在Manage类里面的函数(声明为友元的函数),可以用的是Book类的声明,也就是只用声明class Book,不用包含头文件,因为在头文件中不需要展开具体的函数,因此不需要包含Book类的头文件,只需要在Manage类的cpp文件中包含Book类的头文件即可。
    以下是代码
    main.cpp:
    ---------------------------------------------
    #include <iostream>
    #include "Badao.h"
    #include "Xth.h"
    using namespace std;
    
    int main()
    {
        Badao die;
        Xth one;
        die.use(one);
        cout << "Hello world!" << endl;
        return 0;
    }
    
    Xth.h
    --------------------------------------------
    #ifndef XTH_H
    #define XTH_H
    #include "Badao.h"
    class Badao;
    class Xth
    {
        friend void Badao::use(Xth &);
        public:
            Xth();
            virtual ~Xth();
    
        protected:
    
        private:
            int damage=1000;
    };
    #endif // XTH_H
    
    Xth.cpp
    ------------------------------------------
    #include "Xth.h"
    #include "Badao.h"
    
    Xth::Xth()
    {
        //ctor
    }
    
    Xth::~Xth()
    {
        //dtor
    }
    
    Badao.h
    ------------------------------------------
    #ifndef BADAO_H
    #define BADAO_H
    
    using namespace std;
    class Xth;
    class Badao
    {
        public:
            Badao();
            void use(Xth &);
            virtual ~Badao();
    
        protected:
    
        private:
    };
    
    #endif // BADAO_H
    
    Badao.cpp
    -----------------------------------------
    #include "Badao.h"
    #include <iostream>
    #include "Xth.h"
    
    Badao::Badao()
    {
        //ctor
    }
    void Badao::use(Xth &cw){
        cout<<cw.damage<<endl;
    }
    Badao::~Badao()
    {
        //dtor
    }
    
    
    展开全文
  • 这里重新将类的成员函数的定义看一下:百科上的认识:类的成员函数的原型要在类体中,原型说明了函数的参数表和返回值类型。而函数的定义一般在类外面,也可以直接在类内部定义。前者与普通函数不同的是,实现成员...
  • c++友元函数和友元类

    2021-04-19 14:19:39
    友元函数 友元函数不是本类的成员函数,而是一个外部函数 友元函数的标志就是在类内部加friend关键字来声明 ...友元函数声明的位置不要求,在private或者protected或者public内都可以,...友元函数为外部函数
  • 友元函数

    2014-04-07 21:31:59
    C++中引入友元函数的目的是让函数或类能够访问一...我们知道一个类中的成员函数也是可以访问当前类中的所有私有数据,那么什么不把友元函数写成类自己的成员函数呢?那么我们来举一个简单的例子。 比如函数v
  • 将成员变量声明Private 原因如下: 1,语法一致性,暴露出来的都是函数 2.可以对每一个变量实现权限控制,...宁以非成员、非友元函数替换成员函数 此条款的逻辑是这样的,当我们讨论一个类的封装性的时候。越
  • 6.C++的友元函数和友元类 1.什么是友元函数 1.1、外部函数访问类内成员 ...(5)想办法:除非把disp_info挪到Person类内部成为成员函数,否则没办法 1.2、友元函数的引入 (1)将外部函数disp_info声明Person类的友元
  • 近日了一道题,遇到了新bug,使博主对C++的逻辑严密性有了更深的体会,特写此博客。本文标题是对两个bug的总结,即本文内容分为两部分。 题目如下: 设计一个CShape抽象类,类中包含纯虚函数 从CShape类派生...
  • 理由二:可通过成员函数严格控制其读写权限、添加约束条件。 根本理由:封装性。 声明private则客户只能通过函数接口访问,客户不用关心实现方法,这“所有可能实现”提供了弹性。并且以接口替代直接对变量的...
  • 友元函数/类

    2017-10-13 16:10:10
    如果类A中的函数要访问类B中的成员,类A就得是类B的友元函数,这样类A的成员函数就可以访问类B 中的成员变量 1、普通函数友元函数:  位置:公有私有均可,常写为公有,类内类外均可  方法: friend + ...
  • 题目是:定义Student类和Score类,输出一个学生的成绩单(包括学号、姓名、高数、英语、政治、C++成绩)要求使用Student成员函数作为友元函数 我是这样的(用的是VS2013): **Student.h** ``` #pragma ...
  • 类的成员函数的原型要在类体中,原型说明了函数的参数表和返回值类型。而函数的定义一般在类外面,也可以直接在类内部定义。前者与普通函数不同的是,实现成员函数时要指明类的名称,具体形式: 返回值类型 ...
  •  与运算符重载为成员函数时不同的是,重载的友元函数不属于任何类,运算符的操作数都需要通过函数的形参表传递。操作数在形参表中从左到右出现的顺序就是用运算符表达式时操作数的顺序。  这里也分双目运算符...
  • 这里重新将类的成员函数的定义看一下:百科上的认识:类的成员函数的原型要在类体中,原型说明了函数的参数表和返回值类型。而函数的定义一般在类外面,也可以直接在类内部定义。前者与普通函数不同的是,实现成员...
  • 例如 程序 表示 A = B * 2.75 A = B.operator*(2.75) 但是 A = 2.75 * B 就不能成这样 因为 operator *是成员函数 只有类的...但是由于大部分非成员函数 都不能访问类的数据部分 所以 引入 友元 friend time oper
  • 类的成员函数是指那些把定义和原型在类定义内部的函数,就像类定义中的其他变量一样。 类访问修饰符 类成员可以被定义 public、private 或 protected。默认情况下是定义 private。 构造函数 & ...
  • 在C++中,我们使用类对数据进行了隐藏和封装,类的数据成员一般都定义私有成员,成员函数一般都定义公有的,以此提供类与外界的通讯接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地...
  • 在上面那篇博客中,了将运算符重载普通函数或类的成员函数这两种情况。 以下的两种情况发生。则我们须要将运算符重载类的友元函数 <1>成员函数不能满足要求 <2>普通函数又不能訪问类的私有...
  • 1)请问类中函数 const修饰的谁把类中的成员函数 转换成全局函数成员函数返回*this2)自定义数组类封装 申明 与实现分开 具有以下函数void arr_set(int n,int value);int arr_get(int n);int arr_len()3)什么会有...
  • 今天看到一个算法题,就是如果有两个大整数求和,但是这两个大整数的取值...现在要一个大整数求和的算法,即用两个线性表进行相加,所以要将这个算法函数声明顺序表类的友元函数, 以此来读取类的私有成员!...
  • 成员函数可以访问类中的公有成员,但是,如果将数据成员都定义公有的,这又破坏了隐藏的特性。 另外,应该看到,在某些情况下,特别是在某些成员函数多次被调用时,由于参数传递、类型检查、安全检查等都需要...
  • #include <iostream> //声明类Point using namespace std; class Point { public: ... Point(float x=0,float y=0); //有默认参数的构造函数 ...另有,将point类中重载函数写成inline就不报错了,什么?
  • 类与类之间的或类与某非成员函数之间的简单的操作我们不需要friend比如数据成员的读写,我们可以给数据成员的读写这种操作提供具有public访问权限的inline函数(在某类的public:里inline函数,这个inline函数是...
  • 今天我在项目中了一段代码,这段代码中有两个类A和B,类A中的一个保护成员函数需要访问类B中的私有成员变量,为了简便起见,我将类A中的这个保护成员函数设置成类B的友元函数,在VC下编译通过,没有任何问题。...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 176
精华内容 70
关键字:

友元函数写为成员函数