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. Gson 解决时间解析问题

    异常: at org.eclipse.jdt.) at org.eclipse.jdt.) Caused by: java.text.ParseException: Failed to parse d ...

  2. SecureCRT方向键不可用

    SecureCRT方向键不可用,没有反应 选项--会话选项--终端--仿真

  3. leetcode1017

    这道题目很巧妙,似乎是有些过于巧妙了,属于我未知领域的类型,把原作者的解决方案放这里.(看大家都在给差评,我也顺手给个差评吧--) 参考:https://leetcode.com/problems/c ...

  4. JEECG 3.7.3 新春版本发布,企业级JAVA快速开发平台

    JEECG 3.7.3新春版本发布 -  微云快速开发平台 导读           ⊙精美Echart报表 ⊙二维码生成功能 ⊙Online接口改造采用JWT机制 ⊙智能菜单搜索 ⊙代码生成器模板优 ...

  5. Tomcat 配置Https

    https://www.cnblogs.com/wanghaoyuhappy/p/5267702.html JDK1.8 keytool 生存证书 C:\keys\tomcat.keystore 1: ...

  6. NativeClient开发指南

    https://blog.csdn.net/column/details/24458.html

  7. git安装与基本命令

    一.前言 GibHub的名字源于Git,Git是一个分布式版本控制系统,让程序员团队能够协作开发项目,Git帮助大家管理为项目所做的工作,避免一个人所做的修改影响其他人所做的修改.你在项目中实现一个新 ...

  8. python 可迭代对象与迭代器

    生成器函数的工作原理只要 Python 函数的定义体中有 yield 关键字, 该函数就是生成器函数. 调用生成器函数时, 会返回一个生成器对象. 也就是说, 生成器函数是生成器工厂. 调用生成器函数 ...

  9. Erlang Error Records

    1.No match of right hand value ... Erlang变量名需要以大写开头.

  10. docker之container

    转自:https://www.cnblogs.com/jsonhc/p/7760144.html 运行一个container的本身就是开启一个具有独立namespace的进程 进程有自己的网络,文件系 ...