精华内容
下载资源
问答
  • 如何给友元类设置访问权限友元类无限制地访问所在类的所有元素 #include<iostream> #include<string> #include<algorithm> usingnamespacestd; classStudent; classPerson { ...

    如何给友元类设置访问权限?

    友元类无限制地访问所在类的所有元素

    #include <iostream>    
    #include <string>    
    #include <algorithm>    
    using namespace std;  
      
    class Student;  
      
    class Person  
    {  
        friend class Student; // 显然友元类可以访问Person类中的所有成员(public,private,protected)    
    private:  
        int mark;  
        string name;  
    public:  
        Person() = default;  
        Person(const int& mark, const string& name)  
        {  
            this->mark = mark;  
            this->name = name;  
        }  
        Person& operator = (Person&& obj)  
        {  
            this->mark = obj.mark;  
            this->name = obj.name;  
            return *this;  
        }  
    };  
      
    class Student  
    {  
    private:  
        Person obj;  
    public:  
        Student() = default;  
        Student(const int& mark, const string& name) // const引用允许接受右值    
        {  
            obj = { mark,name }; // 先生成匿名对象,然后调用重载赋值运算符赋值给obj    
        }  
        void ShowInf()  
        {  
            cout << obj.name << "的成绩是" << obj.mark << endl;    
        }  
    };  
      
    int main()  
    {  
        Student obj(99, "张三");  
        obj.ShowInf();  
    }  

     

    上面这个例子表明,如果我们不对友元类加以限制,友元类会彻底地破坏封装,使得类的封装形同虚设,完全地自由地访问所在类的所有成员。

    我们知道:友元函数的访问权限只限于友元声明所在的类的作用域,即如上述例子所示,Student友元类的作用范围仅限于Person类域之内。

    我们想:如何才可以对friend类的访问权限加以限制呢?

    友元类的访问权限设置

    #include <iostream>  
    #include <string>  
    #include <algorithm>  
    using namespace std;  
      
    class Student;  
      
    class Person  
    {  
        //friend class Student; // 显然友元类可以访问Person类中的所有成员(public,private,protected)  
    private:  
        int mark;  
        string name;  
        char age;  
        string schoolname;  
    public:  
        class subclass  
        {  
            friend class Student;  
        private:  
            int mark;  
            string name;  
        public:  
            subclass() = default;  
            subclass(const int& mark, const string& name)  
            {  
                this->mark = mark;  
                this->name = name;  
            }  
            subclass& operator = (subclass&& obj)  
            {  
                this->mark = obj.mark;  
                this->name = obj.name;  
                return *this;  
            }  
            void ShowInf()  
            {  
                cout << this->name << "的成绩是" << this->mark << endl;  
            }  
        } subobj;  
    public:  
        Person() = default;  
        Person(const int& mark,const string& name,const char& age,const string& schoolname)  
        {  
            this->mark = mark;  
            this->name = name;  
            subobj = { mark,name }; // 匿名对象的赋值操作一定要使用右值引用  
            this->age = age;  
            this->schoolname = schoolname;  
        }  
        Person& operator = (Person&& obj)  
        {  
            this->mark = obj.mark;  
            this->name = obj.name;  
            this->age = obj.age;  
            this->subobj = move(obj.subobj);  
            this->schoolname = obj.schoolname;  
            return *this;  
        }  
    };  
      
    class Student  
    {  
    private:  
        Person obj;  
    public:  
        Student() = default;  
        Student(const int& mark, const string& name, const char& age, const string& schoolname) // const引用允许接受右值  
        {  
            obj = { mark,name,age,schoolname }; // 先生成匿名对象,然后调用重载赋值运算符赋值给obj  
        }  
        void ShowInf()  
        {  
            //cout << obj.name << "的成绩是" << obj.mark << endl;  
            obj.subobj.ShowInf();  
        }  
    };  
      
    int main()  
    {  
        Student obj(99, "张三", 'f', "水城中学");;  
        obj.ShowInf();  
    }  

     

    如上述例子所示,friend类访问权限限制方法如下:

     

     

    为什么要声明subclass子类数据成员为共有权限类型,而非私有权限类型?

    Student类不是Person类的友元函数没办法破除封装,Student类是Person.subclass子类成员的友元类,可以破除Person.subclass子类成员的封装,因此声明subclass子类成员为公有属性的数据成员实际上是人为的向外提供了数据访问的接口。Student类中以及任何定义了Person类对象的地方都可以随心所欲的访问subclass子类,但是只有Student类可以破除subclass类成员的封装访问subclass中的所有数据。

     

    展开全文
  • 问题答案是:域内定义的友元函数调用时必须具有该类型实参。解释如下: 首先域内定义的友元函数应该如何看待呢?C++标准规定: 11.4 Friends A function can be defined in a friend ...
    这个问题是个有趣的问题。

    问题的答案是:类域内定义的友元函数调用时必须具有该类类型的实参。解释如下:

    首先类域内定义的友元函数应该如何看待呢?C++标准的规定:

    11.4 Friends

    A function can be defined in a friend declaration of a class if and only if the class is a non-local class (9.8), the function name is unqualified, and the function has namespace scope. [Example:

    class M {
    friend void f() { }   // definition of global f, a friend of M,
                          // not the definition of a member function
    };
    —end example] 
    Such a function is implicitly inline. A friend function defined in a class is in the
    (lexical) scope of the class in which it is defined. A friend function defined outside the class is not (3.4.1).


    f不是qualified-id,但函数体本身处于类域构成的名称空间域内。这意味着,不能使用A::f这样的qualified-id,但调用时又必须体现一个qualified的函数体,这如何做到?还是标准的条款:

    7.3.1.2 Namespace member definitions

    If a friend function is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments (3.4.2).

    当调用一个友元函数时,名字搜索域也包含与实参关联的那些名称空间和类中的名字,于是,一个如下定义的友元函数可以被调用:

    friend void f( A& a ) {}

    但是如果f的形参不是A类型的行不行呢?当然行,但必须具备有效的从A到f形参类型的转换,例如:

    #include <iostream>
    
    class A
    {
    public:
        friend void f( int a ){ }
    
        operator int( ){ return a; }
    
    private:
    
        int a;
    };
    
    int main( void )
    {
        A a;
        f( a );
        return 0;
    }
    

    除此之外都是非法调用。


    展开全文
  • C++类成员的三种访问权限:public:可以被该类中的函数、子类的函数、友元函数访问,也可以由该类的对象访问;protected:可以被该类中的函数、子类的函数、友元函数访问,但不可以由该类的对象访问;private:可以...

    C++使用类对数据进行隐藏和封装,类的数据成员一般定义为私有成员,而将提供类与外界通讯接口的成员函数定义为公有的。

    C++类成员的三种访问权限:

    • public:可以被该类中的函数、子类的函数、友元函数访问,也可以由该类的对象访问;
    • protected:可以被该类中的函数、子类的函数、友元函数访问,但不可以由该类的对象访问;
    • private:可以被该类中的函数、友元函数访问,但不可以由子类的函数、该类的对象、访问。

    但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁访问类的私有(private)成员和保护(protected)成员,这时可以将这些函数定义为友元函数。

    除了友元函数,还有友元类,两者统称为友元(friend)。

    借助友元,可以使得普通函数或其他类中的成员函数可以访问某个类的私有成员和保护成员。

    • 友元函数:普通函数可以访问某个类私有成员或保护成员。
    • 友元类:类A中的成员函数可以访问类B中的私有或保护成员。

    1、友元函数

    友元函数时可以直接访问类的私有成员或保护成员,它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明。

    友元函数的声明格式如下:

    friend 类型 函数名(形参);
    

    示例如下,友元函数 ShowAge() :

    538cc25dc2da68670c9703db2b982fcf.png

    如上图所示,类的友元函数 ShowAge() 定义在类的外部,需要注意的是,尽管 ShowAge() 在类的定义中出现过,但其并不是类的成员函数。

    倘若没有在 Student 类中声明友元函数 ShowAge() ,则其是不能直接访问类的私有成员的,如下图所示。

    02e30edcf7f324517094247fc3c2a787.png

    类的友元函数函数减少了类型检查和安全性检查,提高了程序的运行效率,但它破坏了类的封装性和隐藏性,使得非成员函数也可以访问类的私有成员。

    2、友元类

    友元可以是一个函数,也可以是一个类,该类被称为友元类。

    友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的保护成员和私有成员。

    声明友元类的格式如下:

    friend class 类名;
    

    其中,friend 和 class 是关键字,类名必须是程序中已经定义过的一个类。

    示例如下,类CB是类CA的友元类,可以直接访问类CA的私有成员。

    9f02155b7aec394197c2c4df99ab522a.png

    倘若没有在类CA中声明友元类CB,则CB是不能直接访问CA的私有成员的。

    eb270e03d5f646766cfc15c2fafc2062.png

    使用友元类时,需要注意:

    • 友元关系不能被继承;
    • 友元关系是单向的,不具有交换性。即类B是类A的友元,则类A不一定是类B的友元,需要看类中是否有相应的声明;
    • 友元关系不具有传递性。即类B是类A的友元,类C是类B的友元,但类C不一定是类A的友元,需要看类中是否有相应的声明。

    另外,使用一般不建议把整个类声明为友元类,而只将某些成员函数声明为友元函数,这样更安全些。

    3、友元的优缺点

    利用 friend 修饰符,可以让一些普通函数 或 另一个类的成员函数 直接对某个类的保护成员和私有成员进行操作,提高了程序的运行效率;同时避免把类的成员都声明为public,最大限度地保护数据成员的安全。

    但是,即使是最大限度地保护数据成员,友元也破坏了类的封装性。

    如果将类的封装比喻成一堵墙的话,那么友元机制就像墙上开了一个门。所以使用友元时一定要慎重。

    展开全文
  • 在c++中,模板中可以直接定义一个友元函数,

    原文地址:http://stackoverflow.com/q/23171337/3309790


    在c++中,模板类中可以直接定义一个友元函数,该函数拥有访问该模板类非public成员的权限。比如:

    #include <iostream>
    using namespace std;
    
    template <typename T>
    class template_class {
        T v;
        friend void foo(template_class t) {
            t.v = 1;    // (1)可以访问私有成员因为是友元函数
            cout << t.v << endl;
            template_class<int> t1;
            t1.v = 2;   // (2)可以访问私有成员如果以[T=int]实例化
            cout << t1.v << endl;
            template_class<char> t2;
            t2.v = 'c'; // (3)不可以访问私有成员如果以[T=int]实例化
            cout << t2.v << endl;
        }
    };
    
    int main() {
        template_class<int> t;  //(4)产生(实例化)void foo(template_class<int> t)
        foo(t);
        return 0;
    }

    (4)产生(实例化)出函数void foo(template_class<int>)的定义,并且使得它成为template_class<int>的友元,所以它可以访问template_class<int>的私有成员,正如(1)和(2)所做的。但是(3)应该不可以,因为它并不是template_class<char>的友元,只有void foo(template_class<char>)是template_class<char>的友元。

    但是这段source可以在 gcc 4.8.1上编译通过,但是在clang 3.4编译失败。为什么?这只是一个gcc的bug吗?c++标准对此有明确规定吗?

    /********************************************************************
    * 不落魄的书生的记事簿[blog.csdn.net/songyuanyao]
    ********************************************************************/
    
    展开全文
  • 友元函数的访问权限和注意事项

    千次阅读 2013-06-24 16:33:45
    友元函数要在一个类体内说明,形式为: ...1)必须在类的说明中说明友元函数,说明时以关键字friend开头,后跟友元函数的函数原型,友元函数的说明可以出现在类的任何地方,包括在private和public...
  • coding过程中遇到复杂框架下的类之间相互调用的情况,此时必定绕不开类成员的访问权限问题,典型的是一些自己写的继承自体系结构中已经有的类访问其他类的私有成员或者受保护成员的问题。 此时,应阅读父类代码,...
  • 文章目录const访问权限限定static访问权限限定friend访问权限限定 以上三种关键字限定,归根到底,都是this指针在幕后操作。 const访问权限限定 const对象可以调用非const成员函数吗? 非const对象可以调用...
  • (friend)友元机制:允许一个类将对其非公有成员的访问权限授予指定的函数或者类。 我们可以将友元大致分为3类: 友元函数 友元类 类成员函数的友元 一:友元函数 友元函数:是指某些虽然不是类的成员函数,...
  • 定义: 当一个类B成为了另外一个类A的“朋友”时,那么类A的私有和保护的数据成员就可以...下面这个程序说明了友元类与友元派生类的权限。 class A { public: friend class FriendA; private: int a; ...
  • 友元函数、友元类 “友元”是独立,与类之间不存在包含关系。通过“友元”声明,可以访问类中任何成员。 友元函数 友元函数不是这个类中成员函数,只是一个普通小可爱:在类体外声明、在类体外实现,跟...
  • (1)写一个Person,内部有private、protected、public类访问权限的成员 (2)写一个外部函数disp_info来打印这三成员 (3)代码实战 (4)总结:可以访问public,但是protected和private无法访问 (5)想办法:...
  • 友元类的继承传递

    2017-04-25 21:46:25
    C++ Primer中有如下描述:友元关系不能被继承,基类的友元对派生类没有特殊的访问权限。  然而通过实践发现,VS编译器并没有安装上述描述来处理,下面的规则与上述描述相悖,却符合VS编译器的处理规则。 1 友元类...
  • 友元函数和友元类

    2019-09-26 21:47:16
    类的访问权限限制很大程度上保证了类的安全性。对于私有成员,在类的外部,一般情况下是无法访问的。 但有的时候,又希望在类外能够访问类的私有成员。友元函数就能够实现在类外访问类的成员。 友元函数: 在类...
  • C++类成员的三种访问权限:public:可以被该类中的函数、子类的函数、友元函数访问,也可以由该类的对象访问;protected:可以被该类中的函数、子类的函数、友元函数访问,但不可以由该类的对象访问;private:可以...
  • c++友元函数和友元类

    2021-04-19 14:19:39
    一个外部函数成为类的友元后,访问权限被扩展了,等同于类的内部成员函数了 友元函数是单向的,反过来是不行的 友元函数就好像在类的封装和访问权限保护上打了个“洞”,所以是对面向对象的一种破坏,所以不能...
  • C++ 友元函数与友元类

    2020-04-10 13:42:29
    C++ 友元函数与友元类一、友元函数1、声明2、友元函数作用3、在类中声明友元函数方式4、友元函数注意事项二、友元类1、声明2、注意事项 一、友元函数 1、声明 friend 返回类型 函数名(参数); 2、友元函数...
  • C++类成员的三种访问权限:public:可以被该类中的函数、子类的函数、友元函数访问,也可以由该类的对象访问;protected:可以被该类中的函数、子类的函数、友元函数访问,但不可以由该类的对象访问;private:可以...
  • C++ Primer中有如下描述:友元关系不能被继承,基类的友元对派生没有特殊的访问权限。  然而通过实践发现,VS编译器并没有安装上述描述来处理,下面的规则与上述描述相悖,却符合VS编译器的处理规则。  注...
  • c++类访问权限友元

    2021-04-08 09:43:25
    1.类的访问权限 class是c++的类声明关键字,它的成员类型有三种,是使用三个关键字来声明的,分别是public、private、protected,public声明的叫做公有成员,private声明的是私有成员,protected声明的则是保护成员...
  • 友元函数 友元类

    2014-09-01 15:24:35
    但不要在定义时加上关键字friend,它的访问权限类的成员函数的访问权限相同作用: 把其他类中函数作为自己的友员成员函数,让特定的类成员成为另一个类的友元函数,而不必让整个类成为友元,但在使用时,必须小心排列...
  • 这里写目录标题1. 前言2. 友元函数3. 友元类4. 友元成员函数 1. 前言 友元,一种定义在类外部的普通...通过让函数成为类的友元,可以赋予该函数与类的成员函数相同的访问权限。 用例子说明: //原始类声明 class COrig
  • 若想要类外函数能够访问类的protected和...若想要一个类的成员函数均能访问另一个类的成员,则需要将此类声明为另一个类的友元类。 class A { private: int data; friend class B; }; class B { public: void f...
  • 把函数成为类的友元函数,函数就能访问类的所有成员(成员变量,成员函数),忽视访问权限。 finend 函数定义放到类里,把函数生成成类的友元函数。 class Man : public Human //表示Men是Humen的子类 { private: ...
  • 众所周知,C++控制对类对象私有部分的访问...通过让函数成为类的友元(即:友元函数),可以赋予该函数与类的成员函数相同的访问权限。在介绍如何成为友元前,先介绍为何需要友元。在为类重载二元运算符时(带有两个参
  • 继承方式 继承方式有三种,分别是公有,私有,和受保护继承。 公有 class Base{}; class Dirved1:public{ ...某个类的成员的访问权限受到两个因素影响。 一是基类在该成员的访问符 二是派生类在派生列表中的访问符
  • 1. 基类的友元对派生类的成员没有特殊访问权限。2. 如果基类被授予友元,则只有基类具有特殊访问权限,该基类的派生类无特殊访问权限;3. 但该基类没有被派生类重写且有特殊访问的成员函数仍能被派生类对象直接调用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 603
精华内容 241
关键字:

友元类的访问权限