C++中的public、private、protected

相信很多同学在刚接触c++时一定遇到了和我同样的问题:public、private、protected这三者在使用和访问上到底在哪些地方存在区别?看了很多大牛的博客,决定自己总结下,也分享给和一样同样努力奋斗的程序员。
C++是一种面向对象的语言,其最大的特点就是封装性、继承性。

关于封装性

public和private就是为了这一目的而存在的。用户代码(类外)允许访问public成员却不能访问private成员;private则只能有类内的成员和友元函数(类)访问。关于public和private举个不恰当的例子:public就像你家里的房子,别人是可以看的。而private则是家里的电视家具,只有你的家人(类内成员)或者朋友(友元函数(类))来看or使用。

关于继承性

protected是为这个目的存在的。为什么会有protected这个访问标号的存在呢?我们在使用派生类的时候又是后需要访问基类的private成员,但我们是没有办法做到的。如果把基类的成员设为public那么问题来了,我们并不希望用户代码(类外)进行访问。因此有了protected这个访问标号,他的存在巧妙地解决了上面的问题。基类的protected成员允许派生类访问但不允许用户代码(类外)访问。这里要注意的是允许派生类访问只是允许派生类类内(通过成员函数)访问,派生类实例化的对象是不能访问的。

#include<iostream>
#include<assert.h>
using namespace std;
class Base{
public:
  int a;
  Base(){
    a1 = 1;
    a2 = 2;
    a3 = 3;
    a = 4;
  }
  void fun(){
    cout << a << endl;    //正确
    cout << a1 << endl;   //正确
    cout << a2 << endl;   //正确,类内访问
    cout << a3 << endl;   //正确,类内访问
  }
public:
  int a1;
protected:
  int a2;
private:
  int a3;
};
int main(){
  Base item;
  item.a = 10;    //正确
  item.a1 = 20;    //正确
  item.a2 = 30;    //错误,类外不能访问protected成员
  item.a3 = 40;    //错误,类外不能访问private成员
  return 0;
}

关于继承的访问标号

我们知道关于类的继承形式是这样的:

class Base
{
public:
    void size();
protected:
    int i;
private:
    int j;
}

class Dervied: public Base
{
public:
    void num();
private:
    int k;
}

Dervied继承了Base类,而Dervied:后面的public就是访问标号。
当然除了public继承还有private继承和protected继承,他们三者之间还是有很大区别的。

public继承:
基类成员保持自己的访问级别:基类的public成员为派生类的public成员,基类的protected成员为派生类的protected成员,基类的private成员仍为基类的private成员。

#include<iostream>
#include<assert.h>
using namespace std;

class Base{
public:
  int a;
  Base(){
    a1 = 1;
    a2 = 2;
    a3 = 3;
    a = 4;
  }
  void fun(){
    cout << a << endl;    //正确
    cout << a1 << endl;   //正确
    cout << a2 << endl;   //正确
    cout << a3 << endl;   //正确
  }
public:
  int a1;
protected:
  int a2;
private:
  int a3;
};
class Dervied : public Base{
public:
  int a;
  Dervied(int i){
    Base();
    a = i;
  }
  void fun(){
    cout << a << endl;       //正确,public成员
    cout << a1 << endl;       //正确,基类的public成员,在派生类中仍是public成员。
    cout << a2 << endl;       //正确,基类的protected成员,在派生类中仍是protected可以被派生类访问。
    cout << a3 << endl;       //错误,基类的private成员不能被派生类访问。
  }
};
int main(){
  Dervied b(10);
  cout << b.a << endl;
  cout << b.a1 << endl;   //正确
  cout << b.a2 << endl;   //错误,类外不能访问protected成员
  cout << b.a3 << endl;   //错误,类外不能访问private成员
  return 0;
}

protected继承
基类的public和protected成员在派生类中都为protected成员,基类的private成员仍为基类的private成员。

#include<iostream>
#include<assert.h>
using namespace std;

class Base{
public:
  int a;
  Base(){
    a1 = 1;
    a2 = 2;
    a3 = 3;
    a = 4;
  }
  void fun(){
    cout << a << endl;    //正确
    cout << a1 << endl;   //正确
    cout << a2 << endl;   //正确
    cout << a3 << endl;   //正确
  }
public:
  int a1;
protected:
  int a2;
private:
  int a3;
};

class Dervied : public Base{
public:
  int a;
  Dervied(int i){
    Base();
    a = i;
  }
  void fun(){
    cout << a << endl;       //正确,public成员
    cout << a1 << endl;       //正确,基类的public成员,在派生类中是protected成员。
    cout << a2 << endl;       //正确,基类的protected成员,在派生类中仍是protected可以被派生类访问。
    cout << a3 << endl;       //错误,基类的private成员不能被派生类访问。
  }
};
int main(){
  Dervied b(10);
  cout << b.a << endl;     //正确,public成员,在派生类定义了相同的public成员会覆盖掉基类的成员
  cout << b.a1 << endl;   //错误,类外不能访问protected成员
  cout << b.a2 << endl;   //错误,类外不能访问protected成员
  cout << b.a3 << endl;   //错误,类外不能访问private成员
  return 0;
}

private继承
基类的所有成员在派生类中为private成员

#include<iostream>
#include<assert.h>
using namespace std;

class Base{
public:
  int a;
  Base(){
    a1 = 1;
    a2 = 2;
    a3 = 3;
    a = 4;
  }
  void fun(){
    cout << a << endl;    //正确
    cout << a1 << endl;   //正确
    cout << a2 << endl;   //正确
    cout << a3 << endl;   //正确
  }
public:
  int a1;
protected:
  int a2;
private:
  int a3;
};

class Dervied : public Base{
public:
  int a;
  Dervied(int i){
    Base();
    a = i;
  }
  void fun(){
    cout << a << endl;       //正确,public成员
    cout << a1 << endl;       //正确,基类的public成员,在派生类中变成了private成员。
    cout << a2 << endl;       //正确,基类的protected成员,在派生类中变成了private可以被派生类访问。
    cout << a3 << endl;       //错误,基类的private成员不能被派生类访问。
  }
};
int main(){
  Dervied b(10);
  cout << b.a << endl;     //正确,public成员,在派生类定义了相同的public成员会覆盖掉基类的成员
  cout << b.a1 << endl;   //错误,类外不能访问private成员
  cout << b.a2 << endl;   //错误,类外不能访问private成员
  cout << b.a3 << endl;   //错误,类外不能访问private成员
  return 0;
}

由上面三种继承我们可以看出,派生类可以进一步限制但不能放松对继承的成员的访问。
对于派生类的类内访问继承的访问标号是没有作用的,基类的public和protected可以正常访问,private不能访问。
对于派生类的类外访问继承的访问标号起了决定性的作用,只有继承后为public的成员才能在类内访问。

如果有错误希望批评指正,谢谢~

本博文的代码部分借鉴了http://www.jb51.net/article/54224.htm处的代码,对博主表示感谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值