目录
  • 友元函数
    • 案例
  • 友元类
    • 内部类
      • 总结

        友元分为:友元函数 和 友元类

        友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

        友元函数

        友元函数 可以 直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加 friend 关键字。

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

        案例

        friend ostream& operator<<(ostream& _cout, const Date& d);
        friend istream& operator>>(istream& _cin, Date& d);
        

        cout的输出流对象和隐含的this指针再抢占第一个参数的位置。 this 指针默认是第一个参数也就是左操作数。 但是实际使用中 cout 需要是第一个形参对象, 才能正常使用。

        所以要将 operator<< 重载成全局函数。但是这样的话,又会导致类外没办法访问成员。所以这里就需要友元来解决。

        友元类

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

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

        如果B是A的友元,C是B的友元,则不能说明C时A的友元。

        class A;
        class B;
        
        class A {
        	// 声明B类为A类的友元类,则在B类中就直接访问A类中的私有成员变量
        	friend class B;
        public:
        	A (int a = 0)
        		:_a(a)
        	{}
        private:
        	int _a;
        };
        
        class B {
        public:
        	B(int b = 0)
        		:_b(b)
        	{}
        
        	void SetA(int a)
        	{
        		// 直接访问A类私有的成员变量
        		_aa._a = a;
        	}
        private:
        	int _b;
        	A _aa;
        };
        

        C++的友元和内部类你了解吗

        如果B不是A的友元类,报错。

        内部类

        如果一个类定义在另一个类的内部,这个内部类就叫做内部类。

        此时这个内部类是一个独立的类,他不属于外部类,更不能通过外部类的对象去调用内部类。外部类对内部类没有任何优越的访问权限。

        注:

        内部类就是外部类的友元类。

        内部类可以通过外部类的对象参数来访问外部类中的所有成员,但是外部类不是内部类的友元。

        • 内部类可以定义在 外部类的 publicprotectedprivate
        • 内部类可以直接访问外部类中的 static ,枚举成员,不需要外部类的对象或者类名
        • sizeof(外部类) = 外部类,和内部类没有关系
        class A {
        private:
        	int _a;
        	static int _k;
        
        public:
        	class B {
        	public :
        		void print(const A& aa)
        		{
        			cout << aa._a << endl;
        			cout << _k << endl;
        		}
        	};
        
        	A(int a = 10)
        		:_a(a)
        	{}
        };
        
        int A::_k = 0;
        
        int main()
        {
        	A::B bb;
        	bb.print(A());
        	return 0;
        }
        

        输出:

        10
        0

        总结

        本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注的更多内容!

        声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。