博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c++构造函数,虚函数相关问题
阅读量:2384 次
发布时间:2019-05-10

本文共 1729 字,大约阅读时间需要 5 分钟。

1.c++中内存分布的特点:

全局区(静态区):全局变量,static修饰的局部变量和全局变量,编译时期已经确定

常量区:const修饰的全局变量(const修饰的局部变量还是存储在栈区)和一般的常量(比如字符串),虚函数表(编译时期已经确定下来)

代码区:static修饰的成员函数,一般的成员函数,代码,编译时期已经确定

一般的成员变量和虚函数指针一般是分配在堆或栈中。

一般const修饰的局部变量放在栈区,是可以通过指针对这个变量进行修改的。

这里需要注意一点:如果是在编译时期就已经确定,此时还没有产生对象那为什么,类不能直接调用一般的成员函数,必须通过对象才能调用,因为一般的成员函数里面有一个this指针,必须有一个对象往里面传值,这个函数才能使用

  • 普通成员函数调用流程(大体)

    1. 由于函数地址在编译期间已确定,所以直接找到该函数地址
    2. this指针,作为隐含参数传入该函数
    3. 注意:如果该函数中,使用了实例的成员变量,由于this指针为null,程序会报错
  • 虚函数调用流程(大体)

    1. 查找this指针(也就是实例)的地址
    2. 根据this指针,查找虚函数表(函数指针数组)的地址
    3. 从虚函数表中,取出相应的函数地址

其中,虚函数表是编译时期为每一个类在常量区分配好的一段空间,这个虚函数表实质上是一个函数指针数组,里面存放着该类的虚函数的指针,也就是虚函数的地址。

对于每运行产生的一个对象,为这个对象,且在对象的空间中的第一个位置分配一个指针,这个指针指向虚函数表的第一个位置。

堆区:new一个对象:运行时才能确定

栈区:函数运行分配的空间,栈上分配的对象,也是运行时期确定

2.c++创建一个对象的过程:

1.在栈或者堆中开辟一块空间

2.此时给这块区域填充的是垃圾值

3.根据构造函数给这块区域分配真正的数据

其中,对象初始化有两种方式:1.通过构造函数赋值2.构造函数列表的方式

对于构造函数列表:没有第二步,直接给区域填充正确的值,如果需要填充的变量是由const修饰,只能赋值一次,不可改变。或者就是引用类型,只能赋值一次,不能改变,那么必须使用构造函数列表初始化的方式进行赋值。

构造函数的初始化列表

     –初始化列表可以让构造函数在调用之前进行初始化工作

     –如果类的成员变量是const或引用类型,使用初始化列表是不二选择

3.构造函数被私有化:

导致编译器无法调用该类的构造函数进行对象的初始化工作,但是类中的成员函数可以调用类的构造函数,并且这个成员函数应该写成:static的形式,因为需要直接通过类本身来进行调用,并且应该是public的形式,因为需要为外界提供一个接口,如果这个也设置成private的形式,类外部也访问不了,那么这个类的对象就无法创建,可以在该函数里面new一个对象,该函数可以访问构造函数,这样就产生了一个新的对象。主要目的还是不想让外部随便new一个新对象出来。

4.单例模式:

转载原文地址:

5.虚函数和多重继承:

. 多重继承

转载原文地址:

2. 虚函数表构造过程

从编译器的角度来说,B的虚函数表很好构造,D的虚函数表构造过程相对复杂。下面给出了构造D的虚函数表的一种方式(仅供参考):这个虚函数表的确定是在编译时期已经完成,并且在常量区为其分配空间

当一个类继承多个类,且多个基类都有虚函数时,子类对象中将包含多个虚函数表的指针(即多个vptr),例:

 

其中:D自身的虚函数与B基类共用了同一个虚函数表,因此也称B为D的主基类(primary base class)。

 

虚函数替换过程与前面描述类似,只是多了一个虚函数表,多了一次拷贝和替换的过程。

 

虚函数的调用过程,与前面描述基本类似,区别在于基类指针指向的位置可能不是派生类对象的起始位置,以如下面的程序为例:

适时把自己“归零”,就会不断重新开始,永葆青春。人生最大的敌人莫过于自己。一个人是否成功,大抵决定于在不断把自己“归零”的过程中战胜自己。

6.虚析构函数的作用

首先,如果A的析构函数是虚函数,那么派生类B即使析构函数不是虚函数,编译器也会默认为其加上virtual关键字,变成虚函数的。

 

最后,虚函数和普通成员函数的不同:

 

你可能感兴趣的文章
Eclipse带命令行参数调试
查看>>
php smtp发送邮件
查看>>
wordpress简代码(短代码、shortcode)
查看>>
yii框架的404、500等异常处理
查看>>
yii框架在layout模式下,模版和layout文件的渲染顺序
查看>>
php5对象复制、clone、浅复制与深复制
查看>>
php设计模式
查看>>
git与github在ubuntu下的使用
查看>>
css pie.htc使用总结
查看>>
python包含中文字符串长度
查看>>
sysbench 0.5 性能测试工具使用手册
查看>>
通过telnet连接查看memcache服务器
查看>>
django不用在数据库中创建新的user表而使用它的后台管理功能
查看>>
php array_unshift()修改数组key
查看>>
mysql性能优化-查询(Query)优化-2
查看>>
MySQL分区表的使用
查看>>
MongoDB 地理位置索引的实现原理
查看>>
MongoDB与MySQL的插入、查询性能测试
查看>>
深入理解OAuth2.0协议
查看>>
https原理:证书传递、验证和数据加密、解密过程解析
查看>>