类继承

在C++类继承中,一个派生类可以从一个基类派生,也可以从多个基类派生。 从一个基类派生的继承称为单继承;从多个基类派生的继承称为多继承。

 //单继承的定义
class B:public A
{
< 派生类新定义成员>
};
//多继承的定义
class C:public A,private B
{
< 派生类新定义成员>
};

我们这篇主要说单继承。

派生类共有三种C++类继承方式:

公有继承(public)

  1. 基类的公有成员和保护成员可以作为其派生类的公有成员和保护成员
  2. 派生类的成员函数可以访问基类中的公有成员和保护成员,无法访问基类中的私有成员
  3. 派生类的对象可以访问基类的公有成员

私有继承(private)

  1. 基类的公有成员和保护成员都作为其派生类的私有成员
  2. 在私有继承时,基类的成员只能由直接派生类访问,而无法再往下继承

保护C++类继承(protected)

  1. 基类的所有公有成员和保护成员都成为派生类的保护成员
  2. 基类的公有成员和保护成员只能被它的直接派生类成员函数或友元访问

构造函数和析构函数不能被继承

派生类构造函数一般语法如下:

 派生类名::派生类名(参数总表)
:基类名1(参数表1),...,基类名n(参数表n)
{
初始化语句
}

调用父类构造函数:

 class Parent {
public:
Parent(int x, int y);
}; class SubClass : public Parent {
public:
SubClass(int x, int y) : Parent(x, y){}
};

调用父类函数:

 class A
{
public:
void show()
{
std::cout<<"I am class A"<std::endl;
}
}
class B:public A
{
public:
void dosomething()
{
A::show();
}
}

虚函数

C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。

不定义为虚函数的方法,父类型别的指针指向其子类的实例调用的函数任然是父类的函数。

这个定义放到Java语言中后,可以说Java类中的所有函数都是虚函数。

定义:

 class Base {
public:
virtual void f() { cout << "Base::f" << endl; }
};

纯虚函数

纯虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用。

定义:

 virtual <类型><函数名>(<参数表>)=;

抽象类

C++中并没有abstract这个关键字,一个类是否是抽象类是根据其是否含有纯虚函数来判断的。
抽象类是不能定义对象的,在实际中为了强调一个类是抽象类,可将该类的构造函数说明为受保护的访问控制权限。
抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。如果派生类没有重新定义纯虚函数,而派生类只是继承基类的纯虚函数,则这个派生类仍然还是一个抽象类。如果派生类中给出了基类纯虚函数的实现,则该派生类就不再是抽象类了,它就可以创建该类的实例了。

抽象类的规定:

  1. 抽象类只能用作其他类的基类,不能建立抽象类对象。
  2. 抽象类不能用作参数类型、函数返回类型或显式转换的类型。
  3. 可以定义指向抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性。

嵌套类

在一个类的内部定义另一个类,我们称之为嵌套类(nested class),或者嵌套类型。之所以引入这样一个嵌套类,往往是因为外围类需要使用嵌套类对象作为底层实现,并且该嵌套类只用于外围类的实现,且同时可以对用户隐藏该底层实现。

虽然嵌套类在外围类内部定义,但它是一个独立的类,基本上与外围类不相关。它的成员不属于外围类,同样,外围类的成员也不属于该嵌套类。嵌套类的出现只是告诉外围类有一个这样的类型成员供外围类使用。并且,外围类对嵌套类成员的访问没有任何特权,嵌套类对外围类成员的访问也同样如此,它们都遵循普通类所具有的标号访问控制。

若不在嵌套类内部定义其成员,则其定义只能写到与外围类相同的作用域中,且要用外围类进行限定,不能把定义写在外围类中。例如,嵌套类的静态成员就是这样的一个例子。

前面说过,之所以使用嵌套类的另一个原因是达到底层实现隐藏的目的。为了实现这种目的,我们需要在另一个头文件中定义该嵌套类,而只在外围类中前向声明这个嵌套类即可。当然,在外围类外面定义这个嵌套类时,应该使用外围类进行限定。使用时,只需要在外围类的实现文件中包含这个头文件即可。

另外,嵌套类可以直接引用外围类的静态成员、类型名和枚举成员,即使这些是private的。

 #ifndef NESTCLASS_H_
#define NESTCLASS_H_
class A
{
public:
A();
~A();
void operate();
private:
class B;
B* m_b;
};
#endif
#include "nestclass.h"
#include <iostream>
using namespace std;
class A::B
{
public:
B(){}
~B(){}
void operate()
{
cout<<"B operate!"<<endl;
}
};
A::A()
{
}
A::~A()
{
}
void A::operate()
{
m_b = new B;
cout<<"A operate!"<<endl;
m_b->operate();
}
#include "nestclass.h"
void main()
{
A a;
a.operate();
}

在嵌套类的定义被看到之前我们只能声明嵌套类的指针和引用,如上面在A中定义为B m_b而不是B* m_b将会引发一个编译错误。

C++学习笔记(十二):类继承、虚函数、纯虚函数、抽象类和嵌套类的更多相关文章

  1. Oracle学习笔记十二 子程序(存储过程、自定函数)和程序包

    子程序 子程序:命名的 PL/SQL 块,编译并存储在数据库中.   子程序的各个部分: 1.声明部分 2.可执行部分 3.异常处理部分(可选) 子程序的分类: 1.过程 - 执行某些操作 2.函数 ...

  2. python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL

    python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...

  3. Go语言学习笔记十二: 范围(Range)

    Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...

  4. java jvm学习笔记十二(访问控制器的栈校验机制)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们 ...

  5. JavaScript权威设计--命名空间,函数,闭包(简要学习笔记十二)

    1.作为命名空间的函数 有时候我们需要声明很多变量.这样的变量会污染全局变量并且可能与别人声明的变量产生冲突. 这时.解决办法是将代码放入一个函数中,然后调用这个函数.这样全局变量就变成了 局部变量. ...

  6. (C/C++学习笔记) 十二. 指针

    十二. 指针 ● 基本概念 位系统下为4字节(8位十六进制数),在64位系统下为8字节(16位十六进制数) 进制表示的, 内存地址不占用内存空间 指针本身是一种数据类型, 它可以指向int, char ...

  7. Swift学习笔记十二

    方法 方法就是和某种特定类型相关联的函数.类.结构体.枚举都可以定义实例方法和类型方法.类型方法和OC中的类方法类似. 结构体和枚举也可以定义方法是Swift与C/OC之间很大的一个区别,在OC中,只 ...

  8. Python学习笔记(十二)—Python3中pip包管理工具的安装【转】

    本文转载自:https://blog.csdn.net/sinat_14849739/article/details/79101529 版权声明:本文为博主原创文章,未经博主允许不得转载. https ...

  9. Tomcat学习笔记(十二)

    Host和Engine容器 Context容器的父容器通常是Host容器. Engine容器表示Catalina的整个servlet引擎.如果使用Engine容器,那么它总是处于容器层级的最顶层.默认 ...

  10. IDA Pro 权威指南学习笔记(十二) - IDA 中的注释

    注释有助于以一种更高级的方式描述汇编语言指令序列 IDA 提供了几种不同类型的注释,每种注释适用于不同的目的 使用 Edit -> Comments 命令的选项,可以为反汇编代码清单中的任何一行 ...

随机推荐

  1. Android安全问题 抢先开机启动

    导读:我们以如何抢先开机启动为例,来说明接收无序广播的静态广播接收器的接收顺序 (注意,文本只是陈述结果,所以叫结果篇,之后的文章再给出源码分析) 首先先说一下android中的广播和广播接收器 广播 ...

  2. P134、面试题22:栈的压入、弹出序列

    题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1.2.3.4.5是某栈的压栈序列,序列4,5,3,2,1是该压栈序列对 ...

  3. 睡眠--TASK_INTERRUPTIBLE and TASK_UNINTERRUPTIBLE

    http://i.cnblogs.com/EditPosts.aspx?opt=1   Two states are associated with sleeping, TASK_INTERRUPTI ...

  4. allegro中数据库检查

    1. -------------------- ----

  5. js模仿jquery里的几个方法parent, parentUntil, children

    有时工作需要, 也是接着上一章的方法, 用js模仿jquery里的几个方法parent, parentUntil, children. function parent(node){ return no ...

  6. Hibernate解决高并发问题之:悲观锁 VS 乐观锁

    高并发问题是程序设计所必须要解决的问题,解决此类问题最主要的途径就是对对程序进行加锁控制.hibernate对加锁机制同样做出了实现,常用加锁方式为悲观锁和乐观锁.悲观锁指的是对数据被外界(包括本系统 ...

  7. auto make System.map to C header file

    #!/bin/bash # auto make System.map to C header file # 说明: # 该脚本主要是将Linux内核生成的System.map文件中的符号.地址存入结构 ...

  8. Java [Leetcode 258]Add Digits

    题目描述: Given a non-negative integer num, repeatedly add all its digits until the result has only one ...

  9. jquery 图片上传本地预览V1.2

    基于JQUERY扩展,图片上传预览插件 目前兼容浏览器(IE 谷歌 火狐) 不支持safari 代码进行小小的压缩 如果看源码 自己解压就行了 版本已升级  修复jquery版本问题  支持任意jqu ...

  10. 可用于Hadoop下的ETL工具——Kettle

    看大家分享了好多hadoop相关的一些内容,我为大家介绍一款ETL工具——Kettle.    Kettle是pentaho公司开源的一款ETL工具,跟hadoop一样,也是java实现,其目的就是做 ...