C++中关于public、protect、private的访问权限控制

本文详细介绍了C++中public、protected和private访问控制的特点及应用,包括不同访问级别的成员如何被类实例和成员函数访问,以及在继承过程中的权限变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:成员的访问权限

1: public访问权限

    一个类的public成员变量、成员函数,可以通过类的成员函数、类的实例变量进行访问

   <实际上,类的成员函数,可以访问本类内的任何成员变量和成员函数>

   

#include<iostream>
#include<string>

using namespace std;

class AccessTest
{
	public:
		int pub_mem;
		int pub_fun(){};
	protected:
		int prot_mem;
		int prot_fun(){};
	private:
		int priv_memb;
		int priv_fun(){};
		
};

int main()
{
	AccessTest at;
	at.pub_mem;     //OK, 类变量可以访问public成员
	at.pub_func();  //OK, 访问public成员函数是没有问题的
	
  return 0;
}



2:protected访问权限

     一个类的protected成员变量、成员函数,无法通过类的实例变量进行访问。但是可以通过类的友元函数、友元类进行访问。


#include<string>
#include<iostream>

using namespace std;

class AccessTest
{
    friend void Atest();
    friend class CAtest;
    public:
        int pub_mem;
        void pub_fun(){}
    protected:
        int prot_mem;
        void prot_fun(){}
    private:
        int priv_memb;
        void priv_fun(){}
        
};

class CAtest
{
    public:
        void x()
        {
          AccessTest t;
          t.prot_fun();      //OK,友元类可以访问protected成员函数
          int x=t.prot_mem;  //OK,友元类可以访问protected成员变量
       }
};

void Atest()
{
    AccessTest t;
    t.prot_fun();     //OK,友元函数可以访问protected成员函数
    int x=t.prot_mem;  //OK,友元函数可以访问protected成员变量
}

int main()
{
    AccessTest at;
    at.prot_mem;      //ERROR,类实例变量无法访问protected成员变量
    at.prot_fun();    //ERROR,类实例变量无法访问protected成员函数
    Atest();
    return 0;
}


3:private访问权限

     一个类的private成员变量、成员函数,无法通过类的实例变量进行访问。但是可以通过类的友元函数、友元类进行访问。

#include<iostream>
#include<string>

using namespace std;

class AccessTest
{
	friend void Atest();
	friend class CAtest;
	public:
		int pub_mem;
		void pub_fun(){}
	protected:
		int prot_mem;
		void prot_fun(){}
	private:
		int priv_memb;
		void priv_fun(){}
		
};

class CAtest
{
	public:
	void x()
	{
	       AccessTest t;
    	       t.priv_fun();       //OK,友元类可以访问private成员函数
	       int x=t.priv_memb;  //OK,友元类可以访问private成员变量
        }
};

void Atest()
{
	AccessTest t;
	t.priv_fun();       //OK,友元函数可以访问private成员函数
	int x=t.priv_memb;  //OK,友元函数可以访问private成员变量
}

int main()
{
	AccessTest at;
	at.priv_memb;       //ERROR,类实例变量无法访问private成员变量
	at.priv_fun();      //ERROR,类实例变量无法访问private成员函数
	Atest();
        return 0;
}

到现在,是否感觉私有访问属性,和保护属性没有什么区别?区别主要体现在继承上面。下面将会讲到。


总结:public在任何地方都能访问,protected只能在派生类中访问, private只能在友元中访问。



二:继承的访问权限控制

1:public继承

     派生类通过public继承,基类的各种权限不变 。

     派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。

     派生类的实例变量,可以访问基类的public成员,但是无法访问protected、private成员,仿佛基类的成员之间加到了派生类一般。

     可以将public继承看成派生类将基类的public,protected成员囊括到派生类,但是不包括private成员。

#include<iostream>
#include<string>

using namespace std;

class AccessTest
{
	public:
		int pub_mem;
		void pub_fun(){}
	protected:
		int prot_mem;
		void prot_fun(){}
	private:
		int priv_memb;
		void priv_fun(){}
		
};

class DAccessTest:public AccessTest
{
	public:
		void test()
		{
			int x=pub_mem;     //OK
			pub_fun();         //OK
			
			int y=prot_mem;    //OK
			prot_fun();        //OK
			
			int z=priv_memb;   //ERROR
			priv_fun();        //ERROR
		}
		
};



int main()
{
	DAccessTest dt;
	int x=dt.pub_mem;    //OK
	int y=dt.prot_mem;   //ERROR
	int z=dt.priv_memb;  //ERROR
        return 0;
}


2:protected继承

     派生类通过protected继承,基类的public成员在派生类中的权限变成了protected 。protected和private不变。

     派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。

     派生类的实例变量,无法访问基类的任何成员,因为基类的public成员在派生类中变成了protected。

     可以将protected继承看成派生类将基类的public,protected成员囊括到派生类,全部作为派生类的protected成员,但是不包括private成员。

     private成员是基类内部的隐私,除了友元,所有人员都不得窥探。派生类的友元,都不能访问



#include<iostream>
#include<string>

using namespace std;

class AccessTest
{
    friend void Atest();
    friend class CAtest;
    public:
        int pub_mem;
        void pub_fun(){}
    protected:
        int prot_mem;
        void prot_fun(){}
    private:
        int priv_memb;
        void priv_fun(){}
        
};

class DAccessTest:protected AccessTest
{
    public:
        void test()
        {
            int x=pub_mem;     //OK
            pub_fun();         //OK
            
            int y=prot_mem;    //OK
            prot_fun();        //OK
            
            int z=priv_memb;   //ERROR
            priv_fun();        //ERROR
        }
        
};



int main()
{
    DAccessTest dt;
    int x=dt.pub_mem;    //ERROR,基类的成员现在是派生类的保护成员
    int y=dt.prot_mem;   //ERROR,基类的成员现在是派生类的保护成员
    int z=dt.priv_memb;  //ERROR
  return 0;
}






3:private继承

     派生类通过private继承,基类的所有成员在派生类中的权限变成了private。

     派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。

     派生类的实例变量,无法访问基类的任何成员,因为基类的所有成员在派生类中变成了private。

     可以将private继承看成派生类将基类的public,protected成员囊括到派生类,全部作为派生类的private成员,但是不包括private成员。

     private成员是基类内部的隐私,除了友元,所有人员都不得窥探。派生类的友元,都不能访问


#include<iostream>
#include<string>

using namespace std;

class AccessTest
{
	friend void Atest();
	friend class CAtest;
	public:
		int pub_mem;
		void pub_fun(){}
	protected:
		int prot_mem;
		void prot_fun(){}
	private:
		int priv_memb;
		void priv_fun(){}
		
};

class DAccessTest:private AccessTest
{
	public:
		void test()
		{
			int x=pub_mem;     //OK
			pub_fun();         //OK
			
			int y=prot_mem;    //OK
			prot_fun();        //OK
			
			int z=priv_memb;   //ERROR
			priv_fun();        //ERROR
		}
		
};



int main()
{
	DAccessTest dt;
	int x=dt.pub_mem;    //ERROR,基类的成员现在是派生类的私有成员
	int y=dt.prot_mem;   //ERROR,基类的成员现在是派生类的私有成员
	int z=dt.priv_memb;  //ERROR, private成员无法访问
  return 0;
}

总结:继承修饰符,就像是一种筛子,将基类的成员筛到派生类。public、protected、private,就是筛子的眼。

          通过public继承,所有基类成员(除了private),public、protected都到了派生类里面,public筛眼比较大,不会改变访问权限。

          通过protected继承,所有基类成员(除了private),public、protected都到了派生类里面,protected筛眼大小适中,所有过来的成员都变成了protected。

          通过private继承,所有基类成员(除了private),public、protected都到了派生类里面,private筛眼最小,所有过来的成员都变成了private。

  

PS:关于class和struct的区别

1:class不写修饰符,成员默认是private的,而struct 默认是public的

class Base   //默认private
{
    int a;
    int b;
}

Base ba;
int x=ba.a;//错误
int y=ba.b;//错误

struct St  //默认public
{
    int a;
    int b;
};

St st;
int x=st.a; //OK
int y=st.b;//OK

2:class的继承默认是private的,而struct默认是public的

class Base{...};
class Derive:Base{...}  //private继承

struct BStruct{...};
struct DStruct:BStruct{...};//public继承


### 如何保护C++代码或应用程序 #### 使用编译器优化和混淆技术 为了防止反向工程,可以利用现代编译器提供的各种优化选项来使最终二进制文件更难以被逆向分析。此外,还可以采用专门的工具和服务来进行源码级别的混淆处理,使得即使有人获得了程序的副本也很难理解其工作原理。 #### 动态链接库(DLL)注入防护措施 对于Windows平台上的应用而言,通过`CreateRemoteThread`函数强制其他进程加载特定DLL的做法是一种常见的攻击手段[^2]。为了避免这种情况发生,开发者可以在启动时验证系统的完整性,并监控异常线程活动;也可以考虑实施基于白名单的安全策略,只允许信任的服务访问自己的资源。 #### 加密敏感数据与算法实现细节 如果项目中有重要的商业逻辑或者专有算法,则应该对其进行加密存储,在运行期间再解密执行。这样即便恶意第三方获取到了可执行文件也无法轻易得知核心业务流程是如何运作的。 #### 发布预编译版本而非源码形式的产品 尽可能提供已经过编译的目标机器指令集而不是原始的人类可读语法结构给终端客户安装部署。这一步骤本身就能有效阻止大部分不具备专业知识背景者的窥探企图。 ```cpp // Example of protecting sensitive information within compiled binaries. #include <iostream> #include <string> class SecureData { private: std::string secret; public: explicit SecureData(const char* s):secret(s){}; void showSecret(){ // Decrypt before showing actual content here... std::cout << "The decrypted message is:" << secret << "\n"; } }; int main() { const char *encryptedMessage="ThisIsAnEncryptedString"; SecureData sd(encryptedMessage); sd.showSecret(); } ``` #### 应用软件许可证条款保障权益 最后但同样重要的是,确保遵循合适的开源协议或许可证发布作品。例如GNU通用公共授权许可(GPL),它明确规定了只要求使用者在修改并分发该自由/开放源码软件时也要保持同样的权利给予后续接收者[^3]。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值