c++继承方式和类型兼容的学习

继承方式

  • 公有继承:公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的,不能被这个派生类的子类所访问。
  • 私有继承:私有继承的特点是基类的共有成员和保护成员在继承时都作为派生类的私有成员,派生类的其他成员可以访问,但派生类的对象不可以访问,值得一提的是如果派生类继续作为基类进行派生,基类得全部成员在新的派生类中都无法访问,实际上是中断了基类的继续派生
  • 保护继承:保护继承的特点是基类的共有成员和保护成员在继承时都作为派生类的保护成员,而派生类的私有成员不可直接访问

    保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。

    下面列出三种不同的继承方式的基类特性和派生类特性。

    public protected private
    共有继承 public protected 不可见
    私有继承 private private 不可见
    保护继承 protected protected 不可见

? 下面举个栗子??

公有继承:

#include<iostream>
using?namespace?std;
//////////////////////////////////////////////////////////////////////////
class?A?????? //父类
{
private:
????int?privatedateA;
protected:
????int?protecteddateA;
public:
????int?publicdateA;
};
//////////////////////////////////////////////////////////////////////////
class?B :public?A????? //基类A的派生类B(公有继承)
{
public:
????void?funct()
????{
????????int?b;
????????b=privatedateA;?? //error:基类中私有成员在派生类中是不可见的
????????b=protecteddateA; //ok:基类的保护成员在派生类中为保护成员
????????b=publicdateA;??? //ok:基类的公共成员在派生类中为公共成员
????}
};
//////////////////////////////////////////////////////////////////////////
class?C :private?A? //基类A的派生类C(私有继承)
{
public:
????void?funct()
????{
????????int?c;
????????c=privatedateA;??? //error:基类中私有成员在派生类中是不可见的
????????c=protecteddateA;? //ok:基类的保护成员在派生类中为私有成员
????????c=publicdateA;???? //ok:基类的公共成员在派生类中为私有成员
????}
};
//////////////////////////////////////////////////////////////////////////
class?D :protected?A?? //基类A的派生类D(保护继承)
{
public:
????void?funct()
????{
????????int?d;
????????d=privatedateA;?? //error:基类中私有成员在派生类中是不可见的
????????d=protecteddateA; //ok:基类的保护成员在派生类中为保护成员
????????d=publicdateA;??? //ok:基类的公共成员在派生类中为保护成员
????}
};
//////////////////////////////////////////////////////////////////////////
int?main()
{
????int?a;
?
????B objB;
?//???a=objB.privatedateA;?? //error:基类中私有成员在派生类中是不可见的,对对象不可见
?//???a=objB.protecteddateA; //error:基类的保护成员在派生类中为保护成员,对对象不可见
???a=objB.publicdateA;??? //ok:基类的公共成员在派生类中为公共成员,对对象可见
?
????C objC;
??//??a=objC.privatedateA;?? //error:基类中私有成员在派生类中是不可见的,对对象不可见
??//??a=objC.protecteddateA; //error:基类的保护成员在派生类中为私有成员,对对象不可见
??//?a=objC.publicdateA;??? //error:基类的公共成员在派生类中为私有成员,对对象不可见
?
????D objD;
//????a=objD.privatedateA;?? //error:基类中私有成员在派生类中是不可见的,对对象不可见
//????a=objD.protecteddateA; //error:基类的保护成员在派生类中为保护成员,对对象不可见
//????a=objD.publicdateA;??? //error:基类的公共成员在派生类中为保护成员,对对象不可见
?
????return?0;
}

类型兼容

类型兼容是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。替代之后,派生类对象就可以作为基类对象来使用,但只能使用从基类继承的成员。其包含以下情形:

  1. 派生类对象可以隐含转换为基类对象
  2. 派生类对象可以初始化基类的引用
  3. 派生类的指针可以隐含转换为基类的指针

举个栗子:

class B{...} //定义基类B
class D:public B{...}  //定共有派生类D
B b1,*pb1;
D d1;
//派生类对象隐含转换为基类对象
b1 = d1;
//派生类对象亦可以初始话基类对象的引用
B &rb = d1;
//派生类的地址可以转换为指向基类的指针
pb1 = &d1;

实例:

#include"pch.h"
#include<iostream>

using namespace std;
class Base1 {       //定义基类Base1
public:
    void dispaly() const {
        cout << "Base1;:dispaly()" << endl;
    }
};

class   Base2 :public Base1 {    //定义公有派生类Base2
public :
    void dispaly() const {
        cout << "Base2::display()" << endl;
    }
};

class Derived :public Base2 {
public:
    void display() {
        cout << "Dervied::display()" << endl;
    }
};

void fun(Base1 *ptr){   //参数为指向基类型的指针
    ptr->dispaly();
}

int main() {
    Base1 base1;
    Base2 base2;
    Derived derived;

    fun(&base1);   //用base1对象的指针调用fun函数
    fun(&base2);   //用base2对象的指针调用fun函数
    fun(&derived); //用derived对象的指针调用fun函数
    return 0;
}

运行如下:

由于作者水平有限,以上内容难免有不当之处,还望不吝赐教

原文地址:https://www.cnblogs.com/ma-liner/p/11666375.html

时间: 2024-10-14 09:23:39

c++继承方式和类型兼容的学习的相关文章

C++基础6 【继承】 类型兼容 satatic 多继承 虚继承 【多态】 案例 虚析构函数 重载重写重定义

[继承] 继承的访问控制域 图 类型兼容性原则  指针 与 引用 用子类直接初始化父类 类的继承模型示意 图 [继承结论] [非常重要的概念] 继承与组合混搭情况下,构造和析构调用原则 原则:先构造父类,再构造成员变量.最后构造自己 先析构自己,在析构成员变量.最后析构父类 继承中,同名的成员变量的处理办法 继承中,同名的成员函数的处理办法 派生类中的static关键字 如果静态成员变量,你没有使用,也没有初始化的话 编译不会报错 经典错误 : 类中函数默认是private的,无法在外部访问 具

C++学习15 继承权限和继承方式

C++继承的一般语法为: class 派生类名:[继承方式] 基类名{ 派生类新增加的成员 }; 继承方式限定了基类成员在派生类中的访问权限,包括 public(公有的).private(私有的)和 protected(受保护的).此项是可选的,如果不写,默认为 private 或 protected. 1) public继承方式 基类中所有public成员在派生类中为public属性: 基类中所有protected成员在派生类中为protected属性: 基类中所有private成员在派生类中

js学习总结----深入扩展原型链模式常用的六种继承方式

一.可枚举和不可枚举 for in 循环在遍历的时候,默认的话可以把自己私有的和它所属类原型上的扩展的属性和方法都可以遍历到,但是一般情况下,我们遍历一个对象只需要遍历私有的即可,我们可以使用以下的判断进行处理.obj.propertyIsEnumerable(key) 或者obj.hasOwnProperty(key) 二.Object.create(proObj) 方法创建一个新的对象,但是要把proObj作为这个对象的原型 在IE6-8不兼容(ECMAscript5) 原理: functi

逆战班学习总结 js的几种继承方式

JS中继承的概念: 通过[某种方式]让一个对象可以访问到另一个对象中的属性和方法,我们把这种方式称之为继承 为什么要使用继承? 有些对象会有方法(动作.行为),而这些方法都是函数,如果把这些方法和函数都放在构造函数中声明就会导致内存的浪费 继承的第一种方式:原型链继承 实例修改父节点上的私有属性指向某子节点继承,缺点是其他相同子类会同时一起改变属性 2.继承方式二:借用构造函数 function Father() { this.arr = [1,2,3]} function Son() { //

js的6种继承方式

重新理解js的6种继承方式 注:本文引用于http://www.cnblogs.com/ayqy/p/4471638.html 重点看第三点 组合继承(最常用) 写在前面 一直不喜欢JS的OOP,在学习阶段好像也用不到,总觉得JS的OOP不伦不类的,可能是因为先接触了Java,所以对JS的OO部分有些抵触. 偏见归偏见,既然面试官问到了JS的OOP,那么说明这东西肯定是有用的,应该抛开偏见,认真地了解一下 约定 P.S.下面将展开一个有点长的故事,所以有必要提前约定共同语言: 1 2 3 4 5

重新理解JS的6种继承方式

写在前面 一直不喜欢JS的OOP,在学习阶段好像也用不到,总觉得JS的OOP不伦不类的,可能是因为先接触了Java,所以对JS的OO部分有些抵触. 偏见归偏见,既然面试官问到了JS的OOP,那么说明这东西肯定是有用的,应该抛开偏见,认真地了解一下 约定 P.S.下面将展开一个有点长的故事,所以有必要提前约定共同语言: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /*  * 约定  */ function Fun(){     // 私有属性  

《C#高级编程》【第7章】运算符与类型强制转换 -- 学习笔记

       运算符编程语言的基本元素,它使得我们的代码更加的简洁明了.然而我们为了解决操作数类型不同的问题,我们又有引入了强制转换的概念.我们先看看本章的内容构成吧. 1.运算符 我们来看看一些常见的运算符: <1>条件运算符 其语法如下: Condition ? true_Expression : false_Expression 当条件Condition为真时,其将执行true_Expression,否则执行false_Expression. <2> checked 和

重新理解JS的6种继承方式(转)

http://www.ayqy.net/ 写在前面 一直不喜欢JS的OOP,在学习阶段好像也用不到,总觉得JS的OOP不伦不类的,可能是因为先接触了Java,所以对JS的OO部分有些抵触. 偏见归偏见,既然面试官问到了JS的OOP,那么说明这东西肯定是有用的,应该抛开偏见,认真地了解一下 约定 P.S.下面将展开一个有点长的故事,所以有必要提前约定共同语言: /* * 约定 */ function Fun(){ // 私有属性 var val = 1; // 私有基本属性 var arr = [

TypeScript 类型兼容

在TS中有非常怪异的类型兼容的问题 : 如下 interface  LengthWish{     length : number; } class A{     length : number;     constructor(){         this.length = 2;     } } //定义一个LengthWish类型的变量 let _l : LengthWish = new A(); console.log(`length value is : ${ _l.length }`