一、公有继承(public inheritance)

   1.概念:当类的继承方式为公有继承时,基类的公有成员保护成员的访问属性在派生类中不变,而基类的私有成员不可以直接访问。
   
实验一下:
 
我们用代码实现对概念的理解,如下:
 #include <iostream>
using namespace std; class A{
public:
A():x(),y(){}
A(int x){this->x = x;}
int getx(){return x;}
int gety(){return y;}
int getu(){return u;}
protected:
int y;
private:
int x;
int u;
};
//class B:public A{ //访问公有、保护成员
//
//};
class B:public A{ //通过A中的公有成员函数才能访问A中的私有成员,派生类的成员或者派生类的对象都无法直接访问基类私有成员
public:
// int getx(){return x;} //错误,直接用派生类的成员访问基类私有成员
// int getx(){return A::getx();}
int getx(){return ;} //改造基类成员函数
void sety(){y = ;} //直接调用基类保护成员并修改

};
int main(){
B b;
cout<<"原始的x:"<<b.A::getx()<<endl; //调用基类的同名函数
cout<<"改造后的x:"<<b.getx()<<endl; //调用改造后的函数

cout<<"保护成员y:"<<b.gety()<<endl;
b.sety();
cout<<"在派生类中修改y值:"<<b.gety()<<endl;
cout<<"私有成员u:"<<b.getu()<<endl; //公有继承可以通过派生类的对象访问基类继承的公有成员
// cout<<B::x<<endl; //错误,无法通过派生类成员访问基类私有成员
// cout<<b.y<<endl; //错误, 通过对象无法访问保护成员

return ;
}

执行结果:

 理解:

公有继承方式:

在派生类内部:

1、 派生类成员可以直接访问基类的公有和保护类成员【上面代码23、25行】

2、 当然,如果想拓展继承来的函数可以进行改造,改造是可以同名的,

      在接下来用对派生类的对象调用该函数时就会使用改造后的函数【上面代码24,29行】,

      在后来的调用调用中仍然可以调用基类的未改造的函数【代码28行】

在派生类外部:

1、通过派生类的对象可以访问基类的公有成员(!这里只能访问公有成员,连保护成员都不可以访问)【上面代码35、36行】

2、无论是派生类的成员还是对象都无法直接访问基类私有成员【上面代码36、37行】     

需要注意的是:如果派生类的成员函数与基类的成员函数且你想使用基类的那个函数功能,你需要用  '' 类名::''  这种方式实现。(三种继承方式都是这样)

【上面代码23行】

二、私有继承(private inheritance)

   1.概念:当类的继承方式为私有继承时,基类的公有成员保护成员都以私有成员身份出现在派生类中,而基类的私有成员在派生类中不可直接访问。
 
实验一下:
 
我们仍然使用代码来实现对概念的理解,如下:
 #include <iostream>
using namespace std; class A {
public:
A() : x(), y() {}
int getx() { return x; }
int gety() { return y; }
int getu() { return u; }
protected:
int y;
private:
int x;
int u;
}; class B : private A {
public: //因为基类的公有、保护成员作为派生类的私有成员,派生类的成员不能直接访问它们,
int getx() { return A::getx(); } //只能通过成员函数调用它们 int getyy() { return gety(); } int getyyy(){return y;} //派生类成员中可以直接访问基类继承的公有和保护成员
}; int main() {
B b;
cout <<"x的值:" <<b.getx() << endl;
cout <<"y的值:"<< b.getyy() << endl;
cout<<"y的值:"<<b.getyyy()<<endl;  
// cout<<b.getu()<<endl; //错误,私有继承无法通过派生类对象访问基类成员
return ;
}

执行结果:

理解:

私有继承方式:

在类的内部:

1、由于基类的公有成员和保护成员变成派生类的私有成员,派生类的成员可以直接访问它们【上面代码20、24行】

       

在类的外部:

1、派生类外部无法通过对象直接访问基类的公有成员和保护成员(这是与公有继承的一个差别)【上面代码33行】

       

在派生内外部: 都无法直接访问基类私有成员

 
其实很好理解,基类继承来的公有、保护成员变成派生类的私有成员,想想普通类对私有成员的使用即可。
 
 
 
 
 
 
 
 

三、保护继承(protected inheritance)

   1.概念:保护继承中,基类的公有成员保护成员以保护成员的身份出现在派生类中,而基类的私有成员不可直接访问。
   
实验一下:
 
我们继续用代码实现对概念的理解,如下:
 #include <iostream>
using namespace std; class A{
public:
A():x(),y(){}
int getx(){return x;}
int gety(){return y;}
int getu(){return u;}
protected:
int y;
private:
int x;
int u;
};
class B:protected A{
public:
int getxx(){return getx();} //派生类成员可以直接访问继承来的公有成员【与公有继承一样】
int getyy(){return y;}
};
int main(){
B b;
cout<<"x的值:"<<b.getxx()<<endl;
cout<<"y的值:"<<b.getyy()<<endl; // cout<<b.getx()<<endl; //通过派生类的对象无法直接访问基类成员【与私有继承一样】
// cout<<b.y<<endl;
}

执行结果:

理解:

保护继承方式:

在类内部:

1、继承的公有、保护成员以保护成员存在(存在方式与公有继承的以公有成员存在方式不同),派生类的其它成员可以直接访问

     (这一点与公有、私有继承一致)。【上面代码18、19行】

       

在类外部:

1、通过派生类对象无法直接访问继承的公有、保护成员【上面代码26、27行】(与私有继承一样)

       

在派生类内外部:基类的私有成员都无法直接访问

!!!实践上,在直接派生类中,保护继承的访问属性和私有继承是完全相同的
          但是如果派生类作为新的基类继续派生时二者区别就出现了,我们用代码理解 并 对比:
 
首先:直接继承时使用保护继承:
代码如下:
 #include <iostream>
using namespace std; class A{
public:
A():x(),y(){}
int getx(){return x;}
int gety(){return y;}
int getu(){return u;}
protected:
int y;
private:
int x;
int u;
};
class B:protected A{ //直接继承时 使用保护继承 再看二次继承的效果
public:
int getxx(){return getx();}
int getyy(){return y;}
};
//二次继承无论是私有还是保护继承,二次派生类都可以间接访问初始基类A的公有、保护成员
//class C:private B{
//public:
// int getA_x(){return getx();}
// int getA_y(){return y;}
//};
class D:protected B{
public:
int getA_x(){return getx();}
int getA_y(){return y;}
};

再看:直接继承时使用私有继承

代码如下:

 #include <iostream>
using namespace std; class A{
public:
A():x(),y(){}
int getx(){return x;}
int gety(){return y;}
int getu(){return u;}
protected:
int y;
private:
int x;
int u;
};
class B2:private A{ //直接继承时 使用私有继承 再看二次继承的效果
public:
int getc_x(){return getx();}
int getc_y(){return gety();}
};
//二次继承无论时私有还是保护继承,都无法间接使用初始基类A的成员
class C2:private B2{
public:
// int getA_x(){return getx();} //错误,无法间接访问从初始基类A继承的成员
};
class D2:protected B2{
public:
// int getA_x(){return getx();} //错误,无法间接访问从初始基类A继承的成员
};

上面两块代码,我们主要看直接派生类 B&B2 的继承方式  and   C&C2 、D&D2  能否调用初始基类A的成员

我们发现当直接派生类为私有继承时,通过它在派生的类无法间接访问最初基类成员,

而直接派生类为保护继承时,再通过它派生的成员则可以间接访问最初基类的公有、保护成员。


===============================================================================================================

以上为现阶段学习理解,如有错误,希望指正:)

C++ 中三种继承方式的理解的更多相关文章

  1. c++中三种继承方式的区别

    public公有继承 protected保护继承 private私有继承 我们知道类的private和protected成员,在类外是不可以使用的.只有public成员可以在类外直接使用. 公有继承时 ...

  2. C++中的三种继承方式

    1,被忽略的细节: 1,冒号( :)表示继承关系,Parent 表示被继承的类,public 的意义是什么? class Parent { }; class Child : public Parent ...

  3. C++的三种继承方式详解以及区别

    目录 目录 C++的三种继承方式详解以及区别 前言 一.public继承 二.protected继承 三.private继承 四.三者区别 五.总结 后话 C++的三种继承方式详解以及区别 前言 我发 ...

  4. js的三种继承方式及其优缺点

    [转] 第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = ' ...

  5. C++的三种继承方式简述

    C++对父类(也称基类)的继承有三种方式,分别为:public继承.protected继承.private继承.三种继承方式的不同在于继承之后子类的成员函数的"可继承性质". 在说 ...

  6. C++继承(一) 三种继承方式

    继承定义 继承是使代码可以复用的重要手段,也是面向对象程序设计的核心思想之一. 继承就是不修改原有的类,直接利用原来的类的属性和方法并进行扩展.原来的类称为基类,继承的类称为派生类,他们的关系就像父子 ...

  7. c++三种继承方式public,protect,private

    C++中的三种继承public,protected,private 三种访问权限 public:可以被任意实体访问 protected:只允许子类及本类的成员函数访问 private:只允许本类的成员 ...

  8. C++三种继承方式

    一.三种继承方式 继承方式不同,第一个不同是的是派生类继承基类后,各成员属性发生变化.第二个不同是派生类的对象能访问基类中哪些成员发生变化.表格中红色标注.

  9. mfc 类三种继承方式下的访问

    知识点 public private protected 三种继承方式 三种继承方式的区别 public 关键字意味着在其后声明的所有成员及对象都可以访问. private 关键字意味着除了该类型的创 ...

随机推荐

  1. Docker镜像使用

    当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载. 下面我们来学习: 1.管理和使用本地 Docker ...

  2. python 嵌套字典取值增强版

    def getdictvalue(d,code): result=[] if isinstance(d, dict) : try: value = d[code] result.append(valu ...

  3. 常用的maven仓库地址

    maven 仓库地址: 共有的仓库http://repo1.maven.org/maven2/http://repository.jboss.com/maven2/http://repository. ...

  4. PostgreSQL: Rename a User

    Syntax The syntax to rename a user using the ALTER USER statement in PostgreSQL is: ALTER USER user_ ...

  5. SSH项目中使用struts-tags报错According to TLD or attribute directive in tag file, attribute test does not accept any expressions

    在运行struts2标签页面时报错,代码如下:<%@ page language="java" pageEncoding="gbk"%><%@ ...

  6. 自定义alert弹框,title不显示域名(重写alert)

    问题: 系统默认的alert弹框的title会默认显示网页域名 解决办法: (修改弹框样式) (function() { window.alert = function(name) { $(" ...

  7. 第十二章 Python文件操作【转】

    12.1 open() open()函数作用是打开文件,返回一个文件对象. 用法格式:open(name[, mode[, buffering[,encoding]]]) -> file obj ...

  8. chrome 等浏览器不支持本地ajax请求,的问题

    XMLHttpRequest cannot load file:///D:/WWW/angularlx/ui-router-test/template/content.html. Cross orig ...

  9. JS实现下载的常用方案

    如何使用JS实现异步下载吗?即:既能实现下载又不刷新页面.这时我们常常会想到使用ajax,但是由于ajax接受的response始终是字符串,因此并不能使用ajax来实现下载功能. 常见是新建下载的方 ...

  10. Leetcode: Campus Bikes II

    On a campus represented as a 2D grid, there are N workers and M bikes, with N <= M. Each worker a ...