1,派生类继承了基类的所有成员函数和数据成员(构造函数、析构函数和操作符重载函数外)。

2,当不指明继承方式时,默认为私有继承。

3,基类的私有成员仅在基类中可见,在派生类中是不可见的。基类的私有成员可以由派生类继承,但在派生类中不可见。尽管在派生类中不能直接访问基类的私有成员,但可以通过间接的方式进行访问(设置公有成员访问函数)。

4,改变访问限制:通过使用 using 声明可以改变成员在派生类中的访问限制。

 class BC {
public:
void set_x(float a) { x = a;}
private:
float x;
}; class DC : public BC {
public:
void set_y(float b) { y = b;}
private:
using BC::set_x; // 只写函数名
float y;
};

using 使用示例

5,名字隐藏:如果派生类添加了一个数据成员,而该成员与基类中的某个数据成员同名,新的数据成员就隐藏了继承而来的同名成员,同理,如果派生类添加了与基类的某个成员函数同名的函数,则该函数就隐藏了基类中的同名函数。

 class BC {
public:
void h(float);
}; class DC : public BC {
public:
void h(char []);
}; int main() {
DC d1;
d1.h("Boffo!"); // DC::h,not BC::h
//d1.h(707.7); // *****ERROR:DC:h hides BC::h
d1.BC::h(707.7); // OK: invokes BC::h return ;
}

名字隐藏

6,保护成员:在没有继承的情况下,保护成员和私有成员类似(类的对象不能直接访问保护成员)。保护成员在派生类中是可见的,仅在类层次结构中可见。一般避免将数据成员设计成保护类型,设计一个用来进行存取访问的保护成员函数,通常将这种类型的成员函数称为访问函数。

7,派生类不能访问一个基类对象的保护成员,这是因为基类对象属于基类,不属于派生类。

 class BC {
protected:
int get_w() const;
//...
}; class DC : public BC {
void get_val() const { return get_w();}
void base_w( const BC& b) const { cout<<b.get_w()<<endl; } // ERROR
};

基类对象错误使用示例

8,继承机制下的构造函数:当创建一个派生类对象时,基类的构造函数被自动调用,用来对派生类对象中的基类部分进行初始化,并完成其它一些事务。如果派生类定义了自己的构造函数,则由该构造函数负责对象中“派生类添加部分”的初始化工作。

9,有时候基类的构造函数的功能对派生类而言已经足够,这时候派生类不必自行设计构造函数,否则派生类必须定义自己的构造函数。可以在派生类的构造函数中调用其基类的构造函数(前提是基类拥有构造函数)。

10,在一个层次很深的类层次结构中,创建一个派生类对象将导致派生链中的所有类的构造函数被逐一调用,这是一个多米诺骨牌效应。构造函数的函数体将按照自顶向下(依照继承层次)的次序依次执行。

 class Animal {
public:
Animal() { species = "Animal";}
Animal( const char* s) { species = s;}
private:
string species;
}; class Primate : public Animal {
public:
Primate() : Animal("primate") { }
Primate(int n) : Animal("primate") { heart_cham = n;}
private:
int heart_cham;
}; class Human : public Primate {
public:
Human() : Primate() { }
Human(int c) : Primate(c) { }
};

类继承示例

11,派生类构造函数的规则:如果基类拥有构造函数但没有默认构造函数,那么派生类的构造函数必须显式地调用基类的某个构造函数。一般建议为每个基类都设计一个默认构造函数。

 class BC {
public:
BC(int a) { x = a;y = ;}
BC(int a,int b) { x = a;y = b;}
private:
int x;
int y;
}; class DC : public BC {
public:
DC(int n) { z = n;} // ERROR: DC(int) must explicitly invoke a BC constructor
private:
int z;
};

派生类构造函数规则错误示例

总结:(a)若 DC 有构造函数而 BC 没有,当创建 DC 类的对象时,DC 的相应构造函数被自动调用。

   (b)若 DC 没有构造函数而 BC 有,则 BC 必须拥有默认构造函数,只有这样,当创建 DC 类的对象时,才会自动执行BC 的默认构造函数。

   (c)若 DC 有构造函数,而且 BC 有默认构造函数,则创建 DC 类的对象时,BC 的默认构造函数会自动执行,除非当前被调用的派生类构造函数在其初始化段中显式地调用了 BC 的非默认构造函数。

   (d)若 DC 和 BC 都有构造函数,但 BC 没有默认构造函数,则 DC 的每个默认构造函数必须在其初始化段中显式地调用 BC 的某个构造函数。只有这样,当创建 DC 类的对象时,BC 的构造函数才能获得执行机会。

12,继承机制下的析构函数:析构函数按照派生类到基类的次序执行,因此,析构函数的执行次序和构造函数的执行次序时相反的。由于每个类至多只有一个析构函数,因此对析构函数的调用不会产生二义性,这样在析构函数中不必显式地调用其他析构函数。

 class BC {
public:
BC() { cout<<"BC's constructor"<<endl;}
~BC() { cout<<"BC's destructor"<<endl;}
}; class DC : public BC {
public:
DC() { cout<<"DC's constructor"<<endl;}
~DC() { cout<<"DC's destructor"<<endl;}
}; int main() {
DC d; return ;
} // out
//BC's constructor
//DC's constructor
//DC's destructor
//BC's destructor

析构函数使用示例

13,多继承:在多继承中,一个派生类可以有多个基类,构造的层次结构是图。派生类是其所有基类的组合体。

14,继承和访问规则:使用多继承机制,将增加命名冲突出现的可能性,表现形式有两种:(a)派生类和某个基类之间发生命名冲突;(b)基类与基类之间发生命名冲突。(在单继承中称为名字隐藏),通过使用域解析符来解决。

 class BC1 {
private:
int x;
public:
void set_x(int a) { x = a;}
}; class BC2 {
private:
int x;
public:
void set_x(int a) { x = a;}
}; class DC : public BC1,public BC2 {
private:
int x;
public:
void set_x(int a) { x = a;}
}; int main() {
DC d;
d.set_x(); // local set_x
d.BC1::set_x();
d.BC2::set_x();
return ;
}

命名冲突示例

15,虚基类:解决派生类从同一个间接基类继承了多次(获取了相同的数据成员 x 多次),用虚基类来解决。将 DC1 和 DC2 说明为 z 的虚基类,就是要求 DC1 和 DC2 仅将同名数据成员的一份拷贝发放到 z 当中,而不管 DC1 和 DC2 从共同的祖先获得了多少个同名的数据成员。

 class BC {
int x;
//...
}; class DC1 : virtual public BC { // 改 DC1 为虚基类
//...
}; class DC2 : virtual public BC { // 改 DC2 为虚基类
//...
}; class z : public DC1,public DC2 {
//...
};

虚基类示例

16,保护继承:(a)基类的所有成员在派生类中是保护成员。

        (b)基类中的保护成员在派生类中是保护成员。

        (c) 基类中的所有私有成员仅在基类中可见。

17,私有继承:

        (a)基类的所有成员在派生类中是私有的。

        (b)基类的保护成员在派生类中是私有的。

        (c) 基类的私有成员仅在基类中可见。

c++中的类(class)-----笔记(类继承)的更多相关文章

  1. Python中的类、对象、继承

    类 Python中,类的命名使用帕斯卡命名方式,即首字母大写. Python中定义类的方式如下: class 类名([父类名[,父类名[,...]]]): pass 省略父类名表示该类直接继承自obj ...

  2. ECMAScript6 中 类的封装与继承

    ECMASCRIPT6中实现了class关键字,这样使我们更容易也更形象的进行类的操作 <script type="text/javascript"> class OF ...

  3. C++中public,protected,private派生类继承问题和访问权限问题

    C++中public,protected,private派生类继承问题和访问权限问题 当一个子类从父类继承时,父类的所有成员成为子类的成员,此时对父类成员的访问状态由继承时使用的继承限定符决定. 1. ...

  4. Android(java)学习笔记62:继承Thread类创建线程类

    package cn.itcast_02; /* * 该类要重写run()方法,为什么呢? * 不是类中的所有代码都需要被线程执行的. * 而这个时候,为了区分哪些代码能够被线程执行,java提供了T ...

  5. java中关于类的封装与继承,this、super关键字的使用

    原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/5454849.html. this关键字: this代表当前对象,它有以下几种用途: 1.本类 ...

  6. 实现Square类,让其继承自Rectangle类,并在Square类增添新属性和方法,在2的基础上,在Square类中重写Rectangle类中的初始化和打印方法

    实现Square类,让其继承自Rectangle类,并在Square类增添新属性和方法,在2的基础上,在Square类中重写Rectangle类中的初始化和打印方法 #import <Found ...

  7. Python学习笔记008_类_对象_继承_组合_类相关的BIF

    # 对象 = 属性 + 方法>>> # Python中的类名约定以大写字母开始>>> # tt = Turtle() 这就是创建类实例的方法,其它语言用new ,它 ...

  8. java 学习笔记——类之间的关系之封装、继承与多态的详解

    封装 一个封装的简单例子 封装就是把对象的属性(状态)和方法(行为)结合在一起,并尽可能隐蔽对象的内部细节,成为一个不可分割的独立单位(即对象),对外形成一个边界,只保留有限的对外接口使之与外部发生联 ...

  9. 【游戏开发】在Lua中实现面向对象特性——模拟类、继承、多态

    一.简介 Lua是一门非常强大.非常灵活的脚本语言,自它从发明以来,无数的游戏使用了Lua作为开发语言.但是作为一款脚本语言,Lua也有着自己的不足,那就是它本身并没有提供面向对象的特性,而游戏开发是 ...

  10. ts中的类的定义,继承和修饰符

    自己搞一个ts文件 里面写代码如下,试一下就行了 /* 1.vscode配置自动编译 1.第一步 tsc --inti 生成tsconfig.json 改 "outDir": &q ...

随机推荐

  1. RDD中的cache() persist() checkpoint()

    cache只有一个默认的缓存级别MEMORY_ONLY ,而persist可以根据StorageLevel设置其它的缓存级别. cache以及persist都不是action. 被重复使用的(但是)不 ...

  2. Python3下获取WINDOWS下所有常用系统路径

    #codeing:utf-8import os #搞定WINDOWS下所有系统路径filename='c:\\WINDOWS_ALL_PATH.txt'f=open(filename,'w')i=1f ...

  3. 01.GOF设计模式_概述

    0.Abstract Fcatory 提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类. 1. Adapter 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原 ...

  4. django form 的内置字段类型

    定义的form类如下: from django import forms from django.forms import widgets class AddHouseForm(forms.Form) ...

  5. windows下Jenkins环境搭建

    Jenkins简介 Jenkins是一个开源软件项目,业界著名的持续集成工具. Jenkins 安装准备 1.      安装java 并且配置jdk环境 2.      到Jenkins官网下载Je ...

  6. 机器学习进阶-svm支持向量机

    支持向量机需要解决的问题:找出一条最好的决策边界将两种类型的点进行分开 这个时候我们需要考虑一个问题,在找到一条直线将两种点分开时,是否具有其他的约束条件,这里我们在满足找到一条决策边界时,同时使得距 ...

  7. WPF线性渐变画刷应用之——炫彩线条

    效果图: Xaml代码: <Rectangle Width="800" Height="10"> <Rectangle.Fill> &l ...

  8. 【JEECG技术文档】JEECG高级查询构造器使用说明

    功能介绍   高级查询构造器支持主子表联合查询,查询出更精确的数据. 要使用高级查询构造器需要完成以下步骤: 1. 在高级查询管理配置主子表信息. 2. 配置完后在JSP页面DataGrid标签上添加 ...

  9. vue:在router里面给页面加title

    vue中给组件页面加页面标题:{ path: '/', name: 'index', component: disconnect, meta: { title: '首页' } }, { path: ' ...

  10. vue:监听数据

    1:普通的监听: data () { return { watchNum:1, } }, watch: { watchNum(newValue, oldValue) { console.log(old ...