首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【C++】构造函数分类 ② ( 在不同的内存中创建类的实例对象 | 栈内存中创建实例对象 | new 关键字创建对象 )

一、在不同的内存中创建类的实例对象 1、栈内存中创建实例对象 在上一篇博客 【C++】构造函数分类 ① ( 构造函数分类简介 | 无参构造函数 | 有参构造函数 | 拷贝构造函数 | 代码示例 - 三种类型构造函数定义与调用...栈内存中的 变量 Student s1 ; 这些都是在 栈内存 中创建 类的实例对象 的情况 ; // 调用无参构造函数 Student s1; // 打印 Student s1 实例对象值..., 会自动将栈内存中的实例对象销毁 ; 栈内存中 调用 构造函数 创建的 实例对象 , 不需要关注其内存占用 ; 2、堆内存中创建实例对象 在 栈内存 中声明 类 的 实例对象 方式是 : 该 s1...; Student* s2; 在 C++ 语言中 , 可以使用 new 关键字 , 调用有参构造函数 , 创建类的 实例对象 ; 在下面的 C++ 代码中 , 声明并定义了 MyClass 类 , 该类定义了一个有参构造函数...创建 MyClass 实例对象 , 则不需要关心 该对象 的内存占用情况 , 在这块代码块作用域结束时 , ( 一般是函数大括号内的代码执行完毕 ) , 该 栈内存 中的 MyClass 对象会被系统自动销毁

18920

C++面试题

直接初始化实际上是要求编译器使用普通的函数匹配来选择与我们提供的参数最匹配的构造函数。 拷贝初始化实际上是要求编译器将右侧运算对象拷贝到正在创建的对象中,通常用拷贝构造函数来完成。...当一个构造函数被调用时,它做的首要的事情之一是初始化它的VPTR。因此,它只能知道它是“当前”类的,而完全忽视这个对象后面是否还有继承者。...而析构函数同样也是成员函数,虚析构函数也会进入虚表,唯一不同的是,函数名并不要求一致,而且,你如果不写,编译器也会帮你生成,而且如果基类有virtual,编译器也会默认给子类添加。...当一个元素被插入到一个STL列表(list)中时,列表容器自动为其分配内存,保存数据。考虑到要将STL容器放到共享内存中,而容器却自己在堆上分配内存。...2) 在初始化过程中,会先推断待初始化的元素类型是否为内置类型,若为内置类型POD(Plain Old Data),则直接调用更加底层的函数,上面三个函数相应的底层函数分别为:memmove(b1,b,

1.7K42
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    C++纯虚函数 virtual =0

    1,当想在基类中抽象出一个方法,且该基类只做能被继承,而不能被实例化; 2,这个方法必须在派生类(derived class)中被实现;    如果满足以上两点,可以考虑将该方法申明为pure virtual...也就是说,虚函数实际上是如何被编译器处理的呢?Lippman在深度探索C++对象模型[1]中的不同章节讲到了几种方式,这里把“标准的”方式简单介绍一下。     ...我所说的“标准”方式,也就是所谓的“VTABLE”机制。编译器发现一个类中有被声明为virtual的函数,就会为其搞一个虚函数表,也就是VTABLE。...在创建类实例的时候,编译器还会在每个实例的内存布局中增加一个vptr字段,该字段指向本类的VTABLE。...3.2 构造函数和析构函数中的虚函数调用      一个类的虚函数在它自己的构造函数和析构函数中被调用的时候,它们就变成普通函数了,不“虚”了。也就是说不能在构造函数和析构函数中让自己“多态”。

    1.6K40

    【C++】多态 ⑦ ( 多态机制实现原理 | 虚函数表概念 | 虚函数表工作机制 | vptr 指针 | 虚函数表运行时机制 | 虚函数与动态联编 )

    " 由 C++ 编译器 负责 创建 与 维护 , 被 virtual 关键字 修饰的 虚函数 , 会自动 被 C++ 编译器 存储到 " 虚函数表 " 中 ; 虚函数表 创建 : 在 类 中使用 virtual...vtable ; C++ 编译器 编译 代码时 , 会自动为该类 添加 一个 vptr 指针 成员变量 , 该指针 会指向 虚函数表 ; 5、虚函数表运行时机制 " 虚函数表 " 在 C++ 编译器 编译...C++ 编译器 确定 函数 是否为 virtual 虚函数 ; 非虚函数的静态联编 : 如果 函数 没有被 virtual 关键字修饰 , 该函数 不是 虚函数 , 该函数 可以被确定为 普通 成员函数..., 则使用 " 静态联编 " , 在编译时 就可以确定 是否调用该函数 ; 虚函数的动态联编 : 如果 函数 被 virtual 关键字修饰 , 则该函数是 虚函数 , C++ 编译器编译该类时 ,...; // 创建 Child 子类对象时 // 发现有 virtual 虚函数 会创建 虚函数表 // 在对象中使用 vptr 指针指向 虚函数表 首地址 Child c; 虚函数表 中 存储了

    38130

    硬钢百度面试!

    创建时间少)线程的创建时间比进程快,因为进程在创建的过程中,还需要资源管理信息,比如内存、文件管理信息切换虚拟地址空间,切换内核栈和硬件上下文,页表切换开销很大,而线程在创建的过程中,不会涉及这些信息,...+空类的大小不为0,不同编译器设置不一样,vs和lg++都是设置为1; C++标准指出,不允许一个对象(当然包括类对象)的大小为0,不同的对象不能具有相同的地址; 带有虚函数的C++类大小不为1,因为每一个对象会有一个...所以在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类的状况发生,要将基类的析构函数声明为虚函数。 为什么构造函数不写为虚函数?...而构造函数是在创建对象时自动调用的,不可能通过父类的指针或者引用去调用,因此也就规定构造函数不能是虚函数。...七、C++ sort()函数实现 sort()源码中采用的是一种叫做IntroSort内省式排序的混合式排序算法, 1.首先进行判断排序的元素个数是否大于stl_threshold,stl_threshold

    19920

    轻松搞定面试中的“虚”

    5.是否可以将构造函数声明为virtual? 虚函数的意思就是开启动态绑定,程序会根据对象的动态类型来选择要调用的方法。...(动态绑定是根据对象的动态类型而不是函数名,在调用构造函数之前,这个对象根本就不存在,它怎么动态绑定?) 6.是否可以在析构函数或者构造函数中调用虚函数? 在构造函数不要调用虚函数。...C++中是不可以在构造父类对象部分的时候调用子类的虚函数实现。...为实现动态联编,编译器为每个包含虚函数的类创建一个表,称为vtable,在vtable中,编译器放置了特定类的虚函数地址,在每个带有虚函数的类中编译器会秘密地设置一个虚函数表指针,称为vptr,指向对象的...vtable,通过基类指针做虚函数调用时,也就是多态调用时,编译器静态地插入取得这个vptr,并在vtable表种查找函数地址的代码,这样就能调用正确的函数。

    68120

    《C++虚函数调用开销大揭秘:性能与灵活性的权衡》

    在 C++编程中,虚函数是实现多态性的重要手段之一。它允许我们在运行时根据对象的实际类型来决定调用哪个函数,为程序设计带来了极大的灵活性。然而,这种灵活性并非没有代价,虚函数的调用会带来一定的开销。...那么,C++虚函数的调用开销到底有多大呢?让我们深入探讨这个问题。 一、虚函数的工作原理 在 C++中,当一个类包含虚函数时,编译器会为这个类生成一个虚函数表(vtable)。...虚函数表是一个存储函数指针的数组,每个包含虚函数的类都有一个对应的虚函数表。当创建一个对象时,对象的内存布局中会包含一个指向其所属类的虚函数表的指针。...虚函数表的维护 编译器需要为每个包含虚函数的类生成虚函数表,并在对象的内存布局中添加一个指向虚函数表的指针。这会增加对象的大小,并且在创建和销毁对象时,需要对虚函数表进行维护,这也会带来一定的开销。...虽然虚函数的调用开销在大多数情况下是可以接受的,但是在性能关键的代码路径中,我们需要考虑虚函数的调用开销,并采取一些措施来减少开销。 在选择是否使用虚函数时,我们需要权衡性能和灵活性。

    10410

    游戏编程之十四 游戏使计算机的发展超越了晶体管时代

    这很适合游戏编程来,因为它着重于快速产生平稳的图形。 但DirectDraw最重要的一点在于它对不同的显示适配器具有一个共同的接口。您不必管您的程序它是否会工作。...OLE是微软为在不同的进程和机器间共享信息和服务而引进的基于对象的技术。COM指的是构件对象模型,在OLE编程中,它是接口模型。知道这些概念后就可不理它们了,因为这对我们编程并不重要。...在上例中,指向DirectDraw对象的指针(lpDD)指向了指向vtable的指针(lpVtbl),vtable中包含了对象所有方法的指针,具体地说,本例中指向了SetDisplayMode方法。...); 注意vtable不再显式地使用,C++自动地将对象(lpDD)作为第一个参数。...不需要this指针,因为C++用指向当前对象的指针(本例中为lpDD)隐式地执行该方法。

    6110

    深入浅出 FlatBuffers 之 Encode

    buffer 之后,你将会得到整个数据相对于根的偏移量,通过调用 finish 方法结束创建,这个偏移量会保存在一个变量中,如下代码,偏移量会保存在 orc 变量中: // 调用 `Finish()`...可以看出 struct 的值是直接放入内存中的,没有进行任何处理,而且也不涉及嵌套创建的问题,因此可以内联(inline)在其他结构中。并且存储的顺序和字段的顺序一样。...最后,把 vtable 存储在内存中,以便以后“去重”(相同的 vtable 不创建,修改索引即可) b.vtables = append(b.vtables, b.Offset()) } else...sword 对象先创建,vtable 紧接在它后面,再创建的 axe 对象,所以 axe 对象头部的 offset 为负数。这里为 -12 。...不管压不压缩,flatbuffer 的数据长度都是最长的。JSON 经过压缩以后,数据长度会近似于 protocol buffer。

    7.4K74

    c++虚函数表

    对于一个C++类对象,每个对象有独立的数据成员(非static),但是内存中成员函数只有一份,该类的所有对象共享成员函数。 编译器在编译阶段,进行函数的重构,即将成员函数进行非成员化。...通过将this指针作为函数的第一个参数,通过this指针即可以找到对象的数据成员 使用GDB调试 C++ 虚函数 class Base { public: int a;...构造函数与虚函数表 虚函数表创建时机是在编译期间。 编译期间编译器就为每个类确定好了对应的虚函数表里的内容。...所以在程序运行时,编译器会把虚函数表的首地址赋值给虚函数表指针,所以,这个虚函数表指针就有值了。 ?...ref https://tangocc.github.io/2018/03/20/cpp-class-memory-struct/ TODO 菱形继承于虚继承这里没写,使用gdb也可以很快找到,编译器的规则而已

    68320

    【C++】多态 ⑧ ( 验证指向 虚函数表 的 vptr 指针 | 对比定义了虚函数的类和没有定义虚函数类的大小 )

    的 vptr 指针 是否存在 1、虚函数表与 vptr 指针由来 " 虚函数表 " 由 C++ 编译器 负责 创建 与 维护 , 被 virtual 关键字 修饰的 虚函数 , 会自动 被 C++ 编译器...存储到 " 虚函数表 " 中 ; 虚函数表 创建 : 在 类 中使用 virtual 关键字 声明 虚函数 时 , C++ 编译器 会自动为该类生成 " 虚函数表 " ; 生成虚函数表的前提是 至少有...中 , 重写了 父类的 virtual 虚函数 , 那么 C++ 编译器会在 子类 虚函数表 中放入该 子类虚函数的 函数指针 ; 如果 C++ 类中存在 virtual 虚函数 , 在创建对象时 ,...会生成 虚函数表 Virtual Function Table , 简称 vtable ; C++ 编译器 编译 代码时 , 会自动为该类 添加 一个 vptr 指针 成员变量 , 该指针 会指向 虚函数表...Child 子类对象时 // 发现有 virtual 虚函数 会创建 虚函数表 // 在对象中使用 vptr 指针指向 虚函数表 首地址 Child c; // 将父类指针指向子类对象 p

    22740

    C++中虚拟函数的内存分配机制

    因为虚拟函数的地址翻译取决于对象的内存地址,而不取决于数据类型(编译器对函数 调用的合法性检查取决于数据类型)。...原来,如果类中定义了虚拟函数,该类及其派生类 就要生成一张虚函数表,即vtable。而在类的对象地址空间中存储一个该虚函数表的入口, 占4个字节,这个入口地址是在构造对象是由编译器写入的。...,由于对象的内存空间中包含了虚函数表的入口, 编译器能够由这个入口找到适当的虚函数,这个函数的地址不再由数据类型决定了。...语句pMem = &b;使pMem指向对象b的内存空间,调用pMem->funOver()时, 编译器得到了对象b的vtable入口,并由这个入口找到了CMemSub::funOver()虚函数地址。...到此,虚函数的秘密终于大白于天下了。虚函数是C++语法的重点和难点。

    97720

    C++为什么要弄出虚表这个东西?

    首先声明一点,虚表并非是C++语言的官方标准的一部分,只是各家编译器厂商在实现多态时的解决方案。...C++编译器实际会帮你生成一个类似上例中C语言写法二的形式。这也算是C++ zero overhead(零开销)原则的一个体现。...当然实际并不完全一致,因为C++支持重载的关系,会存在命名崩坏。但主要思想相同,虽不中,亦不远矣。 看到这,你会明白:C++中类和操作的封装只是对于程序员而言的。...而编译器编译之后其实还是面向过程的代码。编译器帮你给成员函数增加一个额外的类指针参数,运行期间传入对象实际的指针。类的数据(成员变量)和操作(成员函数)其实还是分离的。...也就是说在含有虚函数的类编译期间,编译器会自动给这种类在起始位置追加一个虚表指针,一般称之为:vptr。vptr指向一个虚表,称之为:vtable 或vtbl,虚表中存储了实际的函数地址。

    52310

    关于 Spring Boot 中创建对象的疑虑 → @Bean 与 @Component 同时作用同一个类,会怎么样?

    以我的理解,@Configuration 加 @Bean 会创建一个 userName 不为 null 的 UserManager 对象,而 @Component 也会创建一个 userName 为 null...的 UserManager 对象   那么我们在其他对象中注入 UserManager 对象时,到底注入的是哪个对象?   ...因为项目已经上线了很长一段时间了,所以这种写法没有编译报错,运行也没有出问题   后面去找同事了解下,实际是想让   生效,而实际也确实是它生效了   那么问题来了: Spring 容器中到底有几个...创建的 userName 不为 null 的 UserManager 对象   问题又来了:为什么不是 @Component 创建的 userName 为 null 的 UserManager 对象?...和 UserManager 都被扫描出来   注意,此刻 @Bean 的处理还未开始, UserManager 是通过 @Component 而被扫描出来的;此时 Spring 容器中 beanDefinitionMap

    95810

    std和boost的function与bind实现剖析

    用过std和boost的function对象和bind函数的童鞋们都知道这玩意用起来腰不酸了,腿不疼了,心情也舒畅了。...不同的编译器在这基础上有不同的优化,等碰到的地方会大略地提一下,内部的实现原理一样的。...这里在list的实现上boost和std有一点小小的差异。由于boost要兼容老版本的编译器,而老版本编译器是不支持动态模板参数的。...,部分functor数据被直接记在了function里,并且invoker的实现直接采用了C++虚函数)_ 在boost的实现里,每一种function实际绑定的类型都对应着一个静态的vtable对象...正如其名,他模拟了编译器的虚函数表的功能。在function对象被赋值为不同类型的数据的时候,设置为了不同的vtable对象。

    1.8K10

    【C++篇】虚境探微:多态的流动诗篇,解锁动态的艺术密码

    每个对象只包含一个指向虚表的指针(vptr)。虚表本身存储在程序的全局静态区中。每个包含虚函数的类的所有对象共享同一个虚表,而 vptr 是指向这个表的指针。...2.1.1 静态绑定的实现机制: 对于静态绑定,编译器根据对象的声明类型直接生成目标代码。在这种情况下,编译器会直接调用函数的地址,而不需要在运行时查找。...第三章:单继承和多继承中的虚函数表 3.1 单继承中的虚函数表 在单继承的场景下,派生类会继承基类的虚函数表(VTable)。...例如,当调用 Derived 对象的 func1() 时,程序会访问 Base1 的虚表,而调用 func2() 时,程序会访问 Base2 的虚表。...由于这种继承路径,派生类可能会从多个路径继承相同的基类,从而产生两个问题: 数据冗余:每条继承路径都会创建一个独立的基类实例,导致派生类中出现多个相同的基类副本。

    13910

    C++动态联编实现原理分析

    C++标准并没有规定如何实现动态联编,但大多数的C++编译器都是通过虚指针(vptr)和虚函数表(vtable)来实现动态联编。...在不同的编译器中,虚指针在对象中的位置时不同的。两种典型的做法是: (1)在Visual C++中,虚指针位于对象的起始位置; (2)在GNU C++中,虚指针位于对象的尾部而不是头部。...可通过下面的程序考察在Visual C++中,虚指针在对象中的位置。...(1)可以清楚地的看到虚指针对类对象大小的影响。类NoVirtual不包含虚函数,因此类NoVirtual的对象中只包含数据成员i,所以sizeof(NoVirtual)为4。...两种方法都是利用了某种机制逃避C++的类型转换检测,为什么C++编译器干脆不直接放开这个限制,一切让程序员自己作主呢?当然是有原因的,因为类成员函数和普通函数还是有区别的,允许转换后,很容易出错。

    1.7K30

    动态联编实现原理分析

    C++标准并没有规定如何实现动态联编,但大多数的C++编译器都是通过虚指针(vptr)和虚函数表(vtable)来实现动态联编。...一个类只有一个虚函数表,因此类的所有对象中的虚指针都指向同一个地方。在不同的编译器中,虚指针在对象中的位置时不同的。...两种典型的做法是: (1)在Visual C++中,虚指针位于对象的起始位置; (2)在GNU C++中,虚指针位于对象的尾部而不是头部。...(1)可以清楚地的看到虚指针对类对象大小的影响。类NoVirtual不包含虚函数,因此类NoVirtual的对象中只包含数据成员i,所以sizeof(NoVirtual)为4。...两种方法都是利用了某种机制逃避C++的类型转换检测,为什么C++编译器干脆不直接放开这个限制,一切让程序员自己作主呢?当然是有原因的,因为类成员函数和普通函数还是有区别的,允许转换后,很容易出错。

    44520

    《逆袭进大厂》第二弹之C++进阶篇59问59答(超硬核干货)

    我们都知道,C++的赋值操作是会产生临时对象的。临时对象的出现会降低程序的效率。 68、成员列表初始化?...,而它拥有一组参数时; 2) 成员初始化列表做了什么 ① 编译器会一一操作初始化列表,以适当的顺序在构造函数之内安插初始化操作,并且在任何显示用户代码之前; ② list中的项目顺序是由类中的成员声明顺序决定的...假设函数调用使用虚机制,它将仅仅产生通过它自己的VTABLE的调用,而不是最后的VTABLE(全部构造函数被调用后才会有最后的VTABLE)。...在构造一个对象时,由于对象还未创建成功,编译器无法知道对象的实际类型 (2)虚函数的调用需要虚函数表指针vptr,而该指针存放在对象的内存空间中,若构造函数声明为虚函数,那么由于对象还未创建,还没有内存空间...引用在创建的时候必须初始化,在访问虚函数时,编译器会根据其所绑定的对象类型决定要调用哪个函数。注意只能调用虚函数。

    2.4K40
    领券