我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C++关于指针,继承和多态介绍

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C++关于指针,继承和多态介绍

指针

我们在书本上学到的指针基本上都是:首先,指针是一个变量;其次,这个变量存储的值是一个地址。这个是对指针的一个基本理解,最近在编程中发现了一些新的东西。

首先,指针不仅仅是一个地址,还存在一个和所指向内容大小相关的值,如下代码:

#include<iostream>

using namespace std;

int main()
{
    int a = 10;
    int *pa = &a;
    cout << "pa: " << pa << endl;
    cout << "pa+1: " << pa + 1 << endl;

    short b = 1;
    short *pb = &b;
    cout << "pb: " << pb << endl;
    cout << "pb+1: " << pb + 1 << endl;

    void *ppa = &a;
    cout << "ppa:" << ppa << endl;
    cout << "ppa+1: " << ppa + 1 << endl;

    return 0;
}

在这里插入图片描述

从运行结果可以看出pa+1,地址增加了4个字节;pb+1,地址增加了2个字节;ppa+1,地址增加了2个字节;而使用void指针指向整型变量a,此时ppa+1,地址只增加了1个自己。从这个结果我们可以很明显看出,指针不仅仅是一个存地址的变量,还存在一个和内存分配相关的值。其实进一步说,指针不仅仅是一个地址值,还存放着如何解释内存的规则。(void指针只存放地址,没有解释规则)

指针和继承

众所周知,继承可以实现用父类的指针来指向子类的对象,为什么可以这样用呢?正如上面所说,指针保存地址和解释内存的规则,当你声明一个父类指针,那么你就指明了该指针的解释规则,当你将子类地址传给指针时,你就相当于给了一块内存给这个指针,然后这个指针就可以用它的规则去解释这块内存。根据上面的说法,那么我们可以得出,子类对象中必定存在一块内存,其分配方式和父类对象一模一样(如果把这块内存单独提取出来,它就是一个父类对象),事实也是如此,而且这块“父类对象”一般都是存放在子类对象的最前面,这就解释了子类在构造的时候,一定会先调用父类构造函数。同时,“父类对象”指针只能访问自己的父类成员。那么考虑多继承的情况,多继承的子类,其内存空间中必定存在多个“父类对象”空间,这些父类空间的地址必定是不同的,那么就会造成同一个多继承的子类,用其不同的父类指针指向它,其地址值是不同的,实际测试的确如此:

#include<iostream>
using namespace std;
class A
{
    public:
        int a = 10;
        long int aa = 100;
};

class B 
{
    public:
        int b = 20;

};

class C : public A, public B
{
    public:
        int c = 30;
};

int main()
{
    C c;
    A *pA;
    B *pB;
    C *pC;

    pA = &c;
    pB = &c;
    pC = &c;

    cout << "pA: " << pA << endl;
    cout << "pB: " << pB << endl;
    cout << "pC: " << pC << endl;
    cout << "pA.a: " << &(pA->a) << endl;
    cout << "pA.aa: " << &(pA->aa) << endl;
    cout << "pB.b: " << &(pB->b) << endl;
    cout << "pC.c: " << &(pC->c) << endl;

    return 0;
}

在这里插入图片描述

在这里插入图片描述

其内存布局如图,pA、pB都指向各自的“父类对象”空间起始位置,pA只能访问a、aa,pB只能访问b(至于为什么a是int却占8个字节,这个和内存对齐有关,自行查询)。

指针、继承和多态

C++的继承和多态绕不过的一个东西便是虚指针和虚函数,这里简单说一下:首先,在含有虚函数的类中,会产生一个虚函数表,注意这个虚函数表是从属于类的,不是从属于对象,也就是多个对象共享这个虚函数表。其次,每个类声明的对象都会有一个虚指针,这个虚指针指向类的虚函数表。(这里只是简单提及一下,更多的东西可以自行查询)看过很多网上的东西,都说虚指针是每个对象的第一个数据成员,也就是分配在最开头的地址空间。其实,我觉得这句话不完全正确,因为当多继承中有虚函数时,虚函数表就有多个,虚指针也有多个,这些虚指针不一定全都存在于最开始的地址空间。应该说,这些虚指针存在于继承的父类所管理区域的开头:

#include<iostream>
using namespace std;
class A
{
    public:
        int a = 10;
        long int aa = 10;
        virtual void f()
        {

        }
};

class B 
{
    public:
        int b = 20;
        virtual void g()
        {

        }
};

class C : public A, public B
{
    public:
        int c = 30;
        virtual void cc()
        {

        }
};

int main()
{
    A *pA;
    B *pB;
    C c;
    pA = &c;
    pB = &c;
    cout << pA << endl;
    cout << &(pA->a) << endl;
    cout << &(pA->aa) << endl;
    cout << pB << endl;
    cout << &(pB->b) << endl;
    cout << &(c.c) << endl;

    return 0;
}

在这里插入图片描述

在这里插入图片描述

从上面的结果可以看出,虚指针不一定都是存在最开始的位置,如果硬要说是开始,应该也是相对于“父类对象”区域的开始。

到此这篇关于C++关于指针,继承和多态介绍的文章就介绍到这了,更多相关C++指针 继承 多态内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C++关于指针,继承和多态介绍

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python的类、继承和多态简单介绍

这篇文章主要讲解了“Python的类、继承和多态简单介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python的类、继承和多态简单介绍”吧!类的定义假如要定义一个类 Point,表示二维
2023-06-17

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录