[C++]C++中的public/protected/private/friend

一、修饰符public/protect/private

1.修饰谁

C++提供了三种类成员访问修饰符public(公共)、protected(保护)、private(私有)。

可以修饰用于两个地方:

  • 成员前。对于该成员受访范围进行限制。
  • 父类前。对于父类成员能否被继承以及继承成何种成员进行限制。

2.有什么作用

(1)对受访范围的影响

  • 在private下的成员,对于整个类都是可见的,对于友元函数是可见的,对于派生类(子类)是不可见的,对于类的外部是不可见的。
  • 在protected下的成员,对于整个类都是可见的,对于友元函数是可见的,对于派生类(子类)是可见的,对于类的外部是不可见的。
  • 在public下的成员,任何情况都是可见的。

如果没有修饰符,缺省情况是private。

(2)对继承的影响

继承为子类public?继承为子类protected?继承为子类private?
父类public中的成员public继承:Yesprotected继承:Yesprivate继承:Yes
父类protected中的成员public继承:Yes
protected继承:Yes
private继承:Yes
父类private中的成员private成员不能被继承private成员不能被继承private成员不能被继承

总结:父类private中的成员不会被子类继承,父类public和protected中的成员,结合继承时父类的成员访问修饰符,访问范围两者中取小。

#include<iostream.h>
class Base
{  
public:   
	int b_public_x;
	void b_public_fun()
	{
		b_public_x = 1;
		cout << "Base public fun" << endl;
	}      
protected:
	int b_protected_x;
	void b_protected_fun()
	{
		b_protected_x = 1;
		cout << "Base protected fun" << endl;
	}	
private:
	int b_private_x;
	void b_private_fun()
	{
		b_private_x = 1;
		cout << "Base private fun" << endl;
	}
	
};
class Public_Derived : public Base {
public:
	void p_d_public_fun(){
		b_public_x = 2;
		b_protected_x = 2;
		//b_private_x = 2; //wrong,private成员不能被继承
		b_public_fun();
		b_protected_fun();
		//b_private_fun();//wrong,private成员不能被继承
	}
};
class Protected_Derived : protected Base {
public:
	void p_d_public_fun(){
		b_public_x = 2;
		b_protected_x = 2;
		//b_private_x = 2; //wrong,private成员不能被继承
		b_public_fun();
		b_protected_fun();
		//b_private_fun();//wrong,private成员不能被继承
	}
};
class Private_Derived : private Base {
public:
	void p_d_public_fun(){
		b_public_x = 2;
		b_protected_x = 2;
		//b_private_x = 2; //wrong,private成员不能被继承
		b_public_fun();
		b_protected_fun();
		//b_private_fun();//wrong,private成员不能被继承
	}
};
class Public_DDerived : public Public_Derived {
public:
	void p_dd_public_fun(){
		b_public_x = 2;
		b_protected_x = 2;
		b_public_fun();
		b_protected_fun();
	}
};
class Protected_DDerived : protected Public_Derived {
public:
	void p_dd_public_fun(){
		b_public_x = 2;
		b_protected_x = 2;
		b_public_fun();
		b_protected_fun();
	}
};
class Private_DDerived : private Public_Derived {
public:
	void p_dd_public_fun(){
		b_public_x = 2;
		b_protected_x = 2;
		b_public_fun();
		b_protected_fun();
	}
};
int main()
{  

	Base obj;
	obj.b_public_x = 0;
	//obj.b_protected_x = 0;//wrong,protected成员不能在类外被访问
	//obj.b_private_x = 0;//wrong,private成员不能在类外被访问
	obj.b_public_fun();
	//obj.b_protected_fun();//wrong,protected成员不能在类外被访问
	//obj.b_private_fun();//wrong,private成员不能在类外被访问

	Public_Derived obj1;
	obj1.b_public_x = 2;
	//obj1.b_protected_x = 2;//wrong,protected成员不能在类外被访问
	obj1.b_public_fun();
	//obj1.b_protected_fun();//wrong,protected成员不能在类外被访问

	Protected_Derived obj2;
	//obj2.b_public_x = 2;//wrong,protected成员不能在类外被访问
	//obj2.b_protected_x = 2;//wrong,protected成员不能在类外被访问
	//obj2.b_public_fun();//wrong,protected成员不能在类外被访问
	//obj2.b_protected_fun();//wrong,protected成员不能在类外被访问

	Private_Derived obj3;
	//obj3.b_public_x = 2;//wrong,private成员不能在类外被访问
	//obj3.b_protected_x = 2;//wrong,private成员不能在类外被访问
	//obj3.b_public_fun();//wrong,private成员不能在类外被访问
	//obj3.b_protected_fun();//wrong,private成员不能在类外被访问
	
	return 0;    	
}

二、修饰符friend

通常对于普通函数来说,要访问类的保护和私有成员是不可能的。如果想这么做,那么必须把类的成员都设置为public,然而这样带来的问题就是任何外部函数都可以访问它。C++提供friend修饰符,可以让一些你设定的函数能够访问保护和私有成员,避免把类成员全部设置成public,最大限度地保护数据成员的安全。

friend可以修饰用于两个地方:

(1)函数前。在类内声明某个普通函数是本类的友元函数。一个普通函数可以是多个类的友元函数。一个类的成员函数函数也可以是另一个类的友元。

#include <iostream>    
using namespace std;  
class Base    
{    
public:    
    Base(char *name)    
    {    
        strcpy(Base::name,name);        
    }  
friend void ShowN(Base &obj);//友元函数的声明  
public:    
    char name[20];  
};  
  
void ShowN(Base &obj)//友元函数的定义
{  
    cout<<obj.name<<endl;  
}  
void main()    
{  
	Base a="zjgsu";  
    ShowN(a);  
}

(2)类前。整个类是另一个类的友元,该友元可以称为友元类或友类。友类的每个成员函数都可以访问另一个类的所有成员。

下例中,Base是Country的友元类。

#include <iostream>    
using namespace std;  
class Country  
{  
public:  
    Country()  
    {  
        strcpy(cname,"中国");  
    }  
    friend class Base;//友类的声明  
private:  
    char cname[30];  
};  

class Base    //友类的定义
{    
public:    
    Base(char *name)    
    {    
        strcpy(Base::name,name);        
    }  
	void ShowN(Country &temp);
private:    
    char name[20];  
};  

void Base::ShowN(Country &temp)
{  
    strcpy(temp.cname,"中华人民共和国");   
    cout<<name<<endl;  
}  
void main()    
{  
    Base a="zjgsu";  
    Country b;
    a.ShowN(b);  
}

另外,注意几点:

  • 友元关系不可传递。如果A是B的友元,B是C的友元,不代表A是C的友元。
  • 友元关系不能被继承。也就是说父类中的友元不能访问子类私有和保护成员。
  • 友元关系具有单向性。如果A是B的友元,不代表B是A的友元。
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FL1768317420

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值