c++中的类(class)-----笔记(类继承)
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)-----笔记(类继承)的更多相关文章
- Python中的类、对象、继承
类 Python中,类的命名使用帕斯卡命名方式,即首字母大写. Python中定义类的方式如下: class 类名([父类名[,父类名[,...]]]): pass 省略父类名表示该类直接继承自obj ...
- ECMAScript6 中 类的封装与继承
ECMASCRIPT6中实现了class关键字,这样使我们更容易也更形象的进行类的操作 <script type="text/javascript"> class OF ...
- C++中public,protected,private派生类继承问题和访问权限问题
C++中public,protected,private派生类继承问题和访问权限问题 当一个子类从父类继承时,父类的所有成员成为子类的成员,此时对父类成员的访问状态由继承时使用的继承限定符决定. 1. ...
- Android(java)学习笔记62:继承Thread类创建线程类
package cn.itcast_02; /* * 该类要重写run()方法,为什么呢? * 不是类中的所有代码都需要被线程执行的. * 而这个时候,为了区分哪些代码能够被线程执行,java提供了T ...
- java中关于类的封装与继承,this、super关键字的使用
原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/5454849.html. this关键字: this代表当前对象,它有以下几种用途: 1.本类 ...
- 实现Square类,让其继承自Rectangle类,并在Square类增添新属性和方法,在2的基础上,在Square类中重写Rectangle类中的初始化和打印方法
实现Square类,让其继承自Rectangle类,并在Square类增添新属性和方法,在2的基础上,在Square类中重写Rectangle类中的初始化和打印方法 #import <Found ...
- Python学习笔记008_类_对象_继承_组合_类相关的BIF
# 对象 = 属性 + 方法>>> # Python中的类名约定以大写字母开始>>> # tt = Turtle() 这就是创建类实例的方法,其它语言用new ,它 ...
- java 学习笔记——类之间的关系之封装、继承与多态的详解
封装 一个封装的简单例子 封装就是把对象的属性(状态)和方法(行为)结合在一起,并尽可能隐蔽对象的内部细节,成为一个不可分割的独立单位(即对象),对外形成一个边界,只保留有限的对外接口使之与外部发生联 ...
- 【游戏开发】在Lua中实现面向对象特性——模拟类、继承、多态
一.简介 Lua是一门非常强大.非常灵活的脚本语言,自它从发明以来,无数的游戏使用了Lua作为开发语言.但是作为一款脚本语言,Lua也有着自己的不足,那就是它本身并没有提供面向对象的特性,而游戏开发是 ...
- ts中的类的定义,继承和修饰符
自己搞一个ts文件 里面写代码如下,试一下就行了 /* 1.vscode配置自动编译 1.第一步 tsc --inti 生成tsconfig.json 改 "outDir": &q ...
随机推荐
- foreachPartition来写数据库
foreachPartition,在生产环境中,通常来说,都使用foreachPartition来写数据库的 使用批处理操作(一条SQL和多组参数) 发送一条SQL语句,发送一次 一下子就批量插入10 ...
- 64位操作系统(Windows 2008 R2 X64)ASP.NET 调用32位Excel,word 出现401 – 未授权: 由于凭据无效,访问被拒绝。
先确保IIS设置正确,目录权限设置正确. 打开“IIS信息服务管理器”——>选择你发布的网站——>选择功能视图中的“身份验证”——>右键匿名身份验证,选择“编辑”,选择“特定用户“– ...
- ssm学习的第一个demo---crm(1)
这是一个普通的CRM项目 (第一步规划好项目设计路线:导入jar包→配置sqlMapConfig.xml(空文件)→配置applicationContext.xml →配置springMVC.xml→ ...
- JVM虚拟机宕机_java.lang.OutOfMemoryError: unable to create new native thread
原因:当前用户的系统最最大程序数数已达到最大值,使用ulimit -u可以看到是1024 解决办法:在当前用户下使用ulimit -u 65535 然后再执行jsp,一切ok 功能说明:控 ...
- Spring Cloud(2)A Eureka server端 服务注册建立
1. 父项目pom <dependency> <groupId>org.springframework.cloud</groupId> <artifactId ...
- 浅谈如何避免内存泄漏(out of memory)
1.在涉及使用Context时,对于生命周期比Activity长的对象应该使用Application的Context.凡是使用Context优先考虑Application的Context,当然它并不是 ...
- strcore.cpp(156) 内存泄漏
vs搞了一个小工具涉及到线程 每次执行完退出的时候都会报 strcore.cpp(156) 的内存泄漏 原因是在线程内使用了CString 类型的传递参数 如果没有正常释放会报上面的错误.
- idea 常见快捷键记录下
keymaps 选择的是eclipse ctrl shif u 大小写转换 ctrl o 类方法列表 ctrl shif alt u ...
- 文件操作 freopen函数
转自http://blog.csdn.net/zhuyi2654715/article/details/6963673 当我们求解acm题目时,通常在设计好算法和程序后,要在调试环境(例如VC等)中运 ...
- 【388】※ Some useful websites for learning Python
Ref: Python Tips 1. *args and **kwargs 2. Debugging 3. Generators 4. Map, Filter and Reduce 5. set D ...