精华内容
下载资源
问答
  • 在一个类中,可以利用关键字friend将其他的函数或类声明为友元,如果友元是一般函数或者类的成员函数,称为友元函数,...虽然它不是本类的成员函数,但是在它的函数体中可以通过对象访问类的私有和保护成员。 ...

    在一个类中,可以利用关键字friend将其他的函数或类声明为友元,如果友元是一般函数或者类的成员函数,称为友元函数,如果友元是一个类,则成为友元类,友元类的所有成员函数都自动成为友元函数。

    友元函数:

    友元函数是在类中用关键字friend修饰的友元函数,友元函数可以是一个普通的函数,也可以是其他类的成员函数。虽然它不是本类的成员函数,但是在它的函数体中可以通过对象名访问类的私有和保护成员。

    友元普通函数:(将普通函数声明为友元函数)

    #include<iostream>
    using namespace std;
    class Time
    {
    public:
    	Time(int, int, int);
    	friend void display(Time &);//普通函数在类中的声明。
    private:
    	int hour;
    	int minute;
    	int second;
    };
    Time::Time(int h,int m,int s)
    {
    	hour = h;
    	minute = m;
    	second = s;
    }
    void display(Time &t)//普通函数在类中声明为友元
    {
    	cout << t.hour << ":" << t.minute << ":" << t.second << endl;
    }
    int main()
    {
    	Time p(13,42,32);
    	display(p);
    	return 0;
    }

    友元成员函数:

    将一个类中的成员函数去作为另一个类的友元成员函数,

    #include<iostream>
    using namespace std;
    class Date;
    class Time
    {
    public:
    	Time(int, int, int);
    	void display(Date &);
    private:
    	int hour;
    	int minute;
    	int second;
    };
    class Date
    {
    public:
    	Date(int, int, int);
    	friend void Time::display(Date &);
    private:
    	int month;
    	int year;
    	int day;
    };
    Time::Time(int h,int m,int s)
    {
    	hour = h;
    	minute = m;
    	second = s;
    }
    Date::Date(int y, int mon, int d)
    {
    	year = y;
    	month = mon;
    	day = d;
    
    }
    void Time::display(Date &t)
    {
    	cout <<t.year<<":"<<t.month<<":"<<t.day<<","<< hour << ":" << minute << ":" << second << endl;
    }
    int main()
    {
    	Time p(13,42,32);
    	Date q(2019, 4, 29); 
    	p.display(q);
    	return 0;
    }

    以上代码的逻辑上是display是Time类中的一个函数,在定义Time类之前声明了Date类,之后在Time类中声明,display函数的参数是Date类的引用,在Date类中进行声明,添加friend关键字,此时需要添加Time类作用符,之后在类外正常定义。目标就是将Time类的成员函数作为Date类的友元函数,就可以通过该友元函数访问Date类的私有成员

    友元类:

    跟友元函数很相似,可以将一个类作为另一个类的友元类,若A类是B类的友元类,则A类的所有成员函数都是B类的友元函数。都可以去访问B类的私有和保护成员,大概形式为:

    class B;
    class A
    {
       friend Class B;  
    }
    #include<iostream>
    using namespace std;
    class Date;
    class Time
    {
    public:
    	Time(int, int, int);
    	void display(Date &);
    private:
    	int hour;
    	int minute;
    	int second;
    };
    class Date
    {
    public:
    	Date(int, int, int);
    private:
    	int month;
    	int year;
    	int day;
    	friend class Time;
    };
    Time::Time(int h,int m,int s)
    {
    	hour = h;
    	minute = m;
    	second = s;
    }
    Date::Date(int y, int mon, int d)
    {
    	year = y;
    	month = mon;
    	day = d;
    
    }
    void Time::display(Date &t)
    {
    	cout << t.year << ":" << t.month << ":" << t.day << "," << hour << ":" << minute << ":" << second << endl;
    }
    int main()
    {
    	Time p(13,42,32);
    	Date q(2019, 4, 29); 
    	p.display(q);
    	return 0;
    }

    先声明一个Date类,然后自己再去定义一个Time类,之后再具体定义Date类,并自己在类中声明一个友元Time类,不过再Time类中的成员函数display()还需要加上Date &形参,之后按照友元函数操作一样,可以直接就实现了友元类的操作。 

    展开全文
  • 友元友元函数友元类内部再次理解封装匿名对象 再看构造函数 上一章已经看过,在创建一个对象的时候,编译器通过一个构造函数,给对象中的各个成员变量会赋一个合适的初值。 我们想象中的构造函数是这样的 ...

    再看构造函数

    上一章已经看过,在创建一个类的对象的时候,编译器通过一个构造函数,给对象中的各个成员变量会赋一个合适的初值。
    我们想象中的构造函数是这样的

    class Data
    {
    public:
    	Data(int year = 2020, int month = 3, int day = 27)
    	{
    		_year = year;
    		_month = month;
    		_day = day;
    	}
    private:
    	int _year;
    	int _month;
    	int _day;
    };
    

    这样写我们在调用的时候,虽然可以完成赋值的操作,注意是赋值的操作。而我们想要析构函数完成的时候初始化的操作,并不是赋值。这里可能会有疑问,赋值和初始化有什么不一样的?其实真的不一样,一个变量可以有多次赋值的操作,但他却只能被初始化一次,我们所写的这个其实只是一个赋初值的步骤,并不是初始化操作,那么C++是如何解决初始化的问题呢?

    初始化列表

    初始化列表是一个以冒号开始,然后以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或者表达式。

    class Data
    {
    public:
    	Data(int year = 2020, int month = 3, int day = 27)
    		:_year(year)
    		,_month(month)
    		,_day(day)
    	{}
    private:
    	int _year;
    	int _month;
    	int _day;
    };
    

    这样写了看起来就是。。。好神奇。
    注意:

    1. 每个成员变量在初始化列表中只能出现一次,也就是只能初始化一次。
    2. 类中包含(引用的成员变量,const的成员变量,自定义类型的成员-该类没有默认构造函数),这种成员变量必须使用初始化列表进行初始化。因为他们都必须在定义的时候就初始化,而初始化列表就是成员变量定义的位置。

    在这里插入图片描述
    3. 我们在书写的时候,尽量使用初始化列表吧,简洁是一方面,另一方面是无论我们是否使用初始化列表,对于自定义类型的成员变量,都会优先使用初始化列表进行初始化。
    在这里插入图片描述
    4. 成员变量在类中的声明顺序就是在初始化列表中的初始化顺序,跟我们写在初始化列表中的先后次序无关。

    在这里插入图片描述

    explicit关键字

    构造函数不仅可以构造与初始化对象,他们对于单参数的构造函数,还有着类型转换的作用
    在这里插入图片描述
    我们的想法是先用1来构造一个临时对象,再用这个临时对象来对d2进行拷贝构造,从而得到一个新的对象d2。但是C++在这里做了一个优化,就是对于单参数的构造函数,编译器在进行Date d2 = 1 的时候 会自动转化成 d2(1),从而执行d2的构造函数,而不是拷贝构造。
    当然这种方式也是可以禁止的,我们可以在构造函数的的前面加上explicit,这就可以禁止单参构造函数的隐式转换。
    在这里插入图片描述

    static成员

    声明为static的类的成员称为类的静态成员,用static修饰的成员变量称为静态成员变量;
    用static修饰的成员函数叫做静态成员函数。静态的成员变量一定要在类外进行初始化。
    在这里插入图片描述
    特性

    1. 静态成员为所有类对象所共享,不属于某个具体的实例
    2. 静态成员变量必须在类外定义,定义时不添加static关键字。因为声明的时候加过了
    3. 类静态成员即可用类名::静态成员或者对象.静态成员来访问
    4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
    5. 静态成员和类的普通成员一样,也有public、protected、private3种访问级别,也可以具有返回值

    问题

    1. 静态成员函数可以调用非静态成员函数吗?–> 不可以,因为静态成员函数没有this指针,无法做到默认传参这一步,参数始终少一个。
    2. 非静态成员函数可以调用类的静态成员函数吗? --> 可以,因为静态成员函数属于类,只要突破类域就可以调用

    C++11 的成员初始化新玩法。

    C++11支持非静态成员变量在声明时进行初始化赋值,但是要注意这里不是初始化,这里是给声明的成员变量缺省值。

    private:// 非静态成员变量,可以在成员声明时给缺省值。
    	int a = 10;
    	B b = 20;
    	int* p = (int*)malloc(4);
    	static int n;
    

    注意:这里的值只是一个跟缺省参数意义差不多的缺省值,不是初始化

    友元

    友元分为友元函数和友元类。
    C++的三大特性就是封装,继承和多态。而友元提供了一种突破封装的方式,对在不同类之间进行访问提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

    友元函数

    先来重载一个operator<<

    //运算符重载 cout<<Date   --> 初版
    void operator<<(ostream& out)
    {
    	cout << _year << " - " << _month << " - " << _day << endl;
    }
    

    这样写的话要面临的第一个问题就是this指针。因为this在类中是一个默认隐含的参数,他在类中始终占据了第一个默认的参数位置,cout抢不过。。。。平常我们写其他的运算符重载的时候,都是含有this指针的类在运算符的左边 d1 < d2 – operator(Date& d2);,但是cout却在右边。。为了可以使用,我们可以 在调用<<的时候,使用d << cout; 这样就可以跑了,但是看着却有点。。。。
    这时我们想到static可以去掉this参数,试试

    在这里插入图片描述
    这时候再想想,this指针是在类里默认的,也就是说在类外就不会有this默认参数了,使用友元就可以完成这一步骤
    在这里插入图片描述
    但是我们一般写cout函数的时候,可以连续输出多个变量,那么这样的话调用上面那个就不行了。
    联想我们之前写的 x = y = z,Date& operator=(Date& d);,函数加一个返回值就可以了。
    在这里插入图片描述
    接下来我们实现以下cin>>d1>>d2;
    在这里插入图片描述
    说明:

    • 友元函数可访问类的私有和保护成员,但不是类的成员函数
    • 友元函数不能用static,const修饰,不能operator<<() const
    • 友元函数可以在类定义的任何地方声明,不受类访问限定符限制
    • 一个函数可以是多个类的友元函数
    • 友元函数的调用与普通函数的调用和原理相同

    友元类

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

    • 友元关系是单向的,不具有交换性。比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time,类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。
    • 友元关系不能传递。如果B是A的友元,C是B的友元,则不能说明C时A的友元。
    class Time
    {
    	// 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成
    	friend class Date; 
    public:
    	Time(int hour = 21, int minute = 46, int second = 1)
    		: _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)
    	{
    		// 直接访问time类私有的成员变量
    		_t._hour = hour;
    		_t._minute = minute;
    		_t._second = second;
    	}
    
    private:
    	int _year;
    	int _month;
    	int _day;
    	Time _t;
    };
    

    如果A类想要访问B类中私有的成员变量,那么就要在B类中声明A是B的友元,相当于A在访问B类的时候,告诉B类的管家,我是B类的朋友,请让我进来。

    内部类

    • 概念:

    如果一个类定义在另一个类的内部,这个内部类就叫做内部类。注意此时这个内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去调用内部类。外部类对内部类没有任何优越的访问权限。

    • 注意:

    内部类就是外部类的友元类。注意友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。
    特性:

    1. 内部类可以定义在外部类的public、protected、private都是可以的。
    2. 注意内部类可以直接访问外部类中的static、枚举成员,不需要外部类的对象/类名。
    3. sizeof(外部类)=外部类,和内部类没有任何关系

    再次理解封装

    C++通过类,将一个对象的属性与行为结合在一起,使其更符合人们对于一件事物的认知,将属于该对象的所有东西打包在一起;通过访问限定符选择性的将其部分功能开放出来与其他对象进行交互,而对于对象内部的一些实现细节,外部用户不需要知道,知道了有些情况下也没用,反而增加了使用或者维护的难度,让整个事情复杂化。
    在这里插入图片描述

    匿名对象

    在这里插入图片描述
    C++这样也可以定义一个对象。。。。。但是要注意的是,这样生成的匿名对象,他的生命周期只在;后,也就是这一行。为什么呢?匿名的怎么管理啊。。

    展开全文
  • 这个朋友角色的特殊之处在于它可以访问类中所有的成员,包括私有、保护和公有的成员函数和成员变量。这似乎违背了类的封装特性,但这就是友元作为单独的机制出现的原因。有些类需要与其他类进行深♂度 互动,有些...

    友元,顾名思义,是某个类的“朋友”。这个朋友角色的特殊之处在于它可以访问类中所有的成员,包括私有、保护和公有的成员函数和成员变量。这似乎违背了类的封装特性,但这就是友元作为单独的机制出现的原因。有些类需要与其他类进行深♂度 互动,有些函数需要遍历所有类中的成员,这些都是数据封装的例外情况,但也是程序设计中真实会发生的情况。针对这类情况,友元的作用就得以体现了。

    在C++中类的友元共有三大类型:
    1.友元类
    2.友元函数
    3.友元成员函数

    友元的声明
    友元的使用情况具有特殊性,所以所有的友元关系都是单方面的,并且采用授权制。即仅允许一个类设置其他类或函数成为友元,不允许外界将它设置成为友元。
    打个比方,封装好的数据有相当一部分都是私有的(private),属于私人的东西仅可以由他自己单方面授权给其他人看,而不允许其他人自作主张的将别人作为友元并且翻看它的私人物品。

    由于友元仅表示类与函数或类与其他类的特殊关系,因此友元的声明不存在访问控制。也就是说友元的声明可以出现在类中的任意地方而不必考虑是否在public还是在private下。

    将某元素声明成为类的友元,只需要使用关键字friend进行修饰即可:

    友元函数
    一个类可以将一个普通的函数当做友元,允许这个函数访问该类的内部成员。声明方法为:

    friend 返回类型 函数名(参数列表
    展开全文
  • C++友元函数访问类的私有成员

    千次阅读 2017-09-14 15:23:59
    工程中我们经常需要访问一些成员,添加一个友元函数可以达到我们的目的。#include #include using namespace std ;class Student{ private: string name; int age; int sore; public: Student(string name,

    工程中我们经常需要访问一些类的成员,添加一个友元函数可以达到我们的目的。

    #include <iostream>
    #include<cstring>
    using namespace std ;
    
    class Student{
        private:
        string  name;   int age;    int sore;
        public:
        Student(string name,int age,int sore)
        {
            this->name = name;
            this->age = age;
            this->sore = sore;
        }   
        friend void Display(Student student);
    
    } ; 
    
    void Display(Student student)
    {
        cout<<student.name<<"\t"<<student.age<<"\t"<<student.sore<<endl;
    
    }
    
    int main(void)
    {
        Student a("TOM",13,96);
    
        Display(a);
    
        return 0;
    }
    展开全文
  • 以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个“成员变量”后面跟一个放在括号的初始值或表达式。 class A { public: A(int a) :_a(a) {} private: int _a; }; c...
  • 友元函数的总结 我在之前的博客friend友元和内部类 中讲到过,有需要的可以查看:...2)这个友元函数并不是该类的成员函数,它是一个定义在类外的普通函数,只是在类中声明该函数可以直接访问类中的pri...
  •  一个类的私有数据成员通常只能由类的函数成员来访问,而友元函数可以访问类的私有数据成员,也能访问其保护成员 2. 友元函数的用处体现在哪里?  2.1 使用友元函数可提高性能,如:用友元函数重载操作符和生成迭代...
  • 那么,不同行为对类声明的需求如下: 声明友元类,只需要知道该类的存在——前置定义 使用类对象作为参数声明函数,只需要知道该类存在——前置定义 使用类对象作为参数给出函数定义,需要知道类的完整内容——引用...
  • 友元函数、友元类访问私有成员

    千次阅读 2017-05-02 19:16:53
     一个类的私有数据成员通常只能由类的函数成员来访问,而友元函数可以访问类的私有数据成员,也能访问其保护成员 2. 友元函数的用处体现在哪里?  2.1 使用友元函数可提高性能,如:用友元函数重载操作符和生成...
  • 1)友元函数是个函数,只要让普通函数func声明为类A的友元函数,那么func这个函数就能访问类A的所有成员成员变量、成员函数),无论是public,private,protected 2)由于友元函数不属于类成员,所以友元函数的...
  • 友元函数】: 友元函数是指某些虽然不是类成员函数却能够访问类的所有成员的函数。类授予它的友元特别的访问权,这样该友元函数就能访问到类中的所有成员。 如果要声明函数为一个类的友元,需要在类定义中该函数...
  • - 友元类 - 内部 1. 初始化列表 在先前学习的构造函数不能叫做我们的的初始化,只能叫做我们的赋值。因为我们的初始化只能初始化一次,而构造函数可以进行多次赋值 初始化列表语法 初始化列表:以一个冒号...
  • 友元是一种允许非类成员函数访问类的非公有成员的一种机制。可以把一个函数指定为类的友元,也可以把整个类指定为另一个类的友元友元函数友元类 二、友元函数友元函数在类作用域外定义,但它需要在类体中进行说明...
  • C++友元函数友元对象

    2020-07-03 01:14:20
    但是,有时需 要定义一些函数,这 些函数不是类的一部分,但又需要频繁地访问类的数据成员, 这时可以将这些函数定义为该 函数的友元函数。除了友元函数外,还有友元类, 两者统称为友元 友元的作用是提高了程序的运行...
  • 友元函数是一个不属于类成员的函数,但它可以访问的私有成员。换句话说,友元函数被视为好像是该的一个成员友元函数可以是常规的独立函数,也可以是其他成员。实际上,整个都可以声明为另一个友元...
  • 友元的作用:允许让友元类友元函数)访问自己的私有属性 友元的创建方式:在的声明(函数的声明)前面加上友元关键字friend,放在允许被访问私有属性的的里面(不受访问权限限制,随便放,只不过一般我们放在...
  • 友元中的使用

    2018-07-03 08:58:25
    友元中的使用一般分为...这样被声明的友元类即可访问声明处的的所有成员,同时声明的位置不限只需要在中即可。 // Tv 是一个,而Remote则是Tv的遥控器,很显然Remote需要使用Tv // 中的数据进行操作,此时...
  • 搬运自:... ... 友元包括友元函数、友元友元函数: 个人理解为在类中声明的可以外部访问类的内部成员变量的一个函数,这个函数并不是类的成员函数,只是在类中声明,而定义在类外。换...
  • 无法解决的问题:类中声明,类外定义的成员函数,导致无法访问类中的私有成员函数 去掉using namespace std; 改变#include <iostream>啥的都没用 苍了个天,走过路过的帮个忙? 真的是头大,跟着视频敲代码...
  • 友元”的概念其实是针对于类的私有成员来说的,一个类的由于封装的缘故,类体中私有成员是不可以被外界访问的,无论是继承也好,都是无法访问类内私有成员的。但是正是有那么一些人,愿意打破陈规破例访问类体内的...
  • 友元函数、友元类友元成员函数普通函数做类友元函数友元类三级目录 普通函数做类友元函数 #include<iostream> #include<cstdlib> #include<string> #include<vector> using namespace ...
  • 友元与静态成员

    2020-12-19 09:07:24
    友元访问类私有成员的一种途径.友元包括友元函数和友元类. 2.1友元函数  在C++中友元函数允许在类外访问该类中的任何成员,就像成员函数一样,友元函数用关键字friend说明.友元函数可以通过对象访问所有成员,...
  • 众所周知,C++控制对类对象私有部分的访问。通常,公有类方法提供唯一的访问途径,但是有时候这种限制太严格,以至于不适合特定的编程问题。在这种情况下,C++提供了另外一种形式的访问权限:友元友元有3种: ...
  • 一个友元函数可以访问的私有成员 class CCar; //提前声明 CCar, 以便后面CDriver类使用 class CDriver { public: void ModifyCar( CCar * pCar) ; //改装汽车 }; class CCar { private: int price;...
  • 当声明了友元函数或者友元类之后,该函数或者类可以访问类的所有成员,包括private成员,当然访问过程需要通过类的对象进行。例如声明一个友元函数,有两种情况: ①该函数是普通的全局函数 一般情况下,使用一个...
  • C++友元类友元成员函数 1.友元类 如果A是B的友元类,则,A的成员函数都为B的友元函数 声明 class B{ friend class A; ... }; class A { ... }; 举例 class B{ friend class A; private: ...
  • 1.定义在类的外面,可以访问类的保护和私有成员。不是成员函数。 2.友元可以是一个函数,叫友元函数。也可以是一个类,叫友元类。 3.友元,整个类及其所有的成员都是友元。 关键字:friend 4.作用:让类外...
  •  一个类的私有数据成员通常只能由类的函数成员来访问,而友元函数可以访问类的私有数据成员,也能访问其保护成员 2. 友元函数的用处体现在哪里?  2.1 使用友元函数可提高性能,如:用友元函数重载...
  • C++面向对象程序设计实验四静态成员友元 实验目的 掌握静态数据成员的定义初始化和访问方法 掌握静态成员函数的定义和调用方法 掌握友元函数友元类的定义和使用方法 实验内容 1编写程序已有若干只小猫的数据包括...
  • 友元函数不是当前成员函数,而是独立于的外部函数,但它可以访问所有的成员,包括私有成员、保护成员和公有成员。在中声明友元函数,需在其函数名前加上关键字friend,此声明可以放在公有部分、也可以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 25,277
精华内容 10,110
关键字:

友元访问类对象的成员时使用