文档章节

C++ 类继承

KuangCaibao
 KuangCaibao
发布于 2015/04/09 16:43
字数 919
阅读 40
收藏 0

类的继承分为3类:单继承,多继承和虚继承。

1. 单继承
class B {
public:
  int b1;

  B(int init) {
    b1 = init;
  }
};

class D : public B1 {
public:
  int d1;

  D(int init)
  : B1(init - 1)
  {
    d1 = init;
  }
};

int main()
{
  D d(5);
}

这时在内存中可以看到先分配了Base类的空间,这里是4B。关于类大小的计算执行百度。

2. 多继承
class B1 {
public:
  int b1;

  B1(int init) {
    b1 = init;
  }
};

class B2 {
public:
  int b2;

  B2(int init) {
    b2 = init;
  }
};

class D : public B1, public B2 {
public:
  int d1;

  D(int init)
  : B1(init - 1)
  , B2(init - 2)
  {
    d1 = init;
  }
};

这时的内存图为:

现在单继承和多继承有点了解了,那么如果多继承中的2个基类 B1, B2 又同时继承于类 A,这时内存是如何表现的。

class A {
  public:
    int a1;
    A(int init) { a1 = init; }
};

class B1 : public A { ... };
class B2 : public A { ... };

/* 这里的流程如上面的多继承 */

内存图:

这样的静态分配看出没有任何的问题,我们使用指针去访问类A的变量a1。

D d(5);
// A *p = (A *)&d; // 语法错误
B1 *p1 = (B1 *)&d;
A *p = (A *)p1;
cout << p->a1 << endl;  // 3

B2 *p2 = (B2 *)&d;
p = (A *)p2;
cout << p->a1 << endl;  // 2

// d.a1 = 1; // 这时会报错,因为这个时候不知道指定的a1变量是哪个。

擦,这个编译器还是可以根据对应的继承关系找到对应的值的。叼,这里有个问题,因为现在我们都带了初始化的变量,这时从B1, B2分别实例化的A具有不同的值,但是如果我们想想这种情形。如果类A中是一些需要实现的方法,按这种方式,我们需要分别在 B1 , B2中分别去实现 A 的方法,如果需要实现的类方法是有差异的,那么这样的做法就是正确的。但是如果我们需要实现的类方法是一样的,那么这里A的每个方法在内存中就有重复的2个版本,这样就造成了空间的浪费。这里可以使用虚继承。

3. 虚函数
class B {
  public:
    int b;
    B(int init) { b = init; }
    void Print() { cout << b << endl; }
    virtual void vPrint() { cout << b << endl; }
};

class D : public B {
  public:
    int d;
    D(int init):B(init-1) { d = init; }
    void Print() { cout << d << endl; }
    virtual void vPrint() { cout << d << endl; }
};

int main() 
{
  D d(5);
  B *pb = (B *)&d; // 使用基类指针
  
  d.Print();    // 5
  pb->Print();  // 4
  pb->vPrint(); // 5
}

内存图:

可以看到,类D的实例化变量 d 的大小为12,只包含了 本身和基类的变量和一个虚函数指针的地址。这里应该称为虚函数表的地址指针。

虚函数在继承的时候会发生覆盖,这从程序的执行结果和内存图中都可以看到。而对于类中的一般函数,则没有覆盖现象的发生。

如果在基类中我们只定义一些函数,而不去实现它,这时就需要使用到纯函数,这种一般都是让这些函数在派生类中去实现,这样可以称为接口。

virtual void Print()=0; // 纯虚函数定义  virtual [返回类型] [函数名]([变量列表]) = 0;

当类中又这样的纯虚函数定义存在的时候,这时的类称为抽象类,在语法上是不允许被实例化的。因为其中的函数需要派生类去实现。

4. 虚继承
class A {
  public:
    int a;
    A() { a = 3; }
};

class B1 : virtual public A {
  public:
    int b1;
    B1() { b1 = 4; }
};

class B2 : virtual public A {
  public:
    int b2;
    B2() { b2 = 5; }
};

class C : virtual public B1, virrual public B2 {
  public:
    int c;
    C() { c = 6; }
};

int main()
{
  C c;
  return 0;
}

内存图:

内存的分配还是有点不清楚。

© 著作权归作者所有

上一篇: MinGW
下一篇: C++ 杂项
KuangCaibao
粉丝 2
博文 21
码字总数 10699
作品 0
武汉
程序员
私信 提问
《鸡啄米C++编程入门系列》系列技术文章整理收藏

《鸡啄米C++编程入门系列》已整理成PDF文档,点击可直接下载至本地查阅 https://www.webfalse.com/read/201812.html 文章 鸡啄米:C++编程入门系列之前言 鸡啄米:C++编程入门系列之一(进制...

开元中国2015
2015/06/27
88
0
c语言基础学习11_项目实战:IDE(集成开发环境)

============================================================================= ============================================================================= 涉及到的知识点有: 一......

黑泽明军
2018/01/29
0
0
Android Camera 模块分析(四)

3.3 Camera本地库libui.so frameworks/base/libs/ui/中的Camera.cpp文件用于实现Camera.h提供的接口,其中一个重要的片段如下所示: const sp<ICameraService>& Camera::getCameraService()......

Jerikc
2012/08/31
402
0
C++ STL编程轻松入门 2

1.3.3 STL和GP,GP和OOP   正如前面所提到的,在STL的背后蕴含着泛型化程序设计(GP)的思想,在这种思想里,大部分基本算法被抽象,被泛化,独立于与之对应的数据结构,用于以相同或相近的...

暖冰
2015/11/21
232
0
C++ 接口

C++中有多继承,多继承很好,但是c++多重继承中,派生类继承了所有父类的实现,导致体积膨胀等缺点。C#和java的设计者坚持单继承,所有的类都派生自Object类,他们提供了interface来模仿c++的...

长平狐
2012/08/28
126
0

没有更多内容

加载失败,请刷新页面

加载更多

golang-字符串-地址分析

demo package mainimport "fmt"func main() {str := "map.baidu.com"fmt.Println(&str, str)str = str[0:5]fmt.Println(&str, str)str = "abc"fmt.Println(&s......

李琼涛
今天
4
0
Spring Boot WebFlux 增删改查完整实战 demo

03:WebFlux Web CRUD 实践 前言 上一篇基于功能性端点去创建一个简单服务,实现了 Hello 。这一篇用 Spring Boot WebFlux 的注解控制层技术创建一个 CRUD WebFlux 应用,让开发更方便。这里...

泥瓦匠BYSocket
今天
6
0
从0开始学FreeRTOS-(列表与列表项)-3

FreeRTOS列表&列表项的源码解读 第一次看列表与列表项的时候,感觉很像是链表,虽然我自己的链表也不太会,但是就是感觉很像。 在FreeRTOS中,列表与列表项使用得非常多,是FreeRTOS的一个数...

杰杰1号
今天
8
0
Java反射

Java 反射 反射是框架设计的灵魂(使用的前提条件:必须先得到代表的字节码的 Class,Class 类 用于表示.class 文件(字节码)) 一、反射的概述 定义:JAVA 反射机制是在运行状态中,对于任...

zzz1122334
今天
6
0
聊聊nacos的LocalConfigInfoProcessor

序 本文主要研究一下nacos的LocalConfigInfoProcessor LocalConfigInfoProcessor nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/impl/LocalConfigInfoProcessor.java p......

go4it
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部