首页
学习
活动
专区
圈层
工具
发布

c++学习笔记4,调用派生类的顺序构造和析构函数(一个)

大家好,又见面了,我是全栈君 测试源代码: //測试派生类的构造函数的调用顺序何时调用 //Fedora20 gcc version=4.8.2 #include using namespace...endl; } }; 測试代码: int main() { A a; A *a1; cout调用基类的构造函数..."<<endl; A *a2=new A; //仅仅有在new 一个对象的时候才会调用基类的构造函数 cout调用基类的构造函数"<<endl; A *a3=&a; B b; } 输出为: 能够看到,在创建派生类的对象的时候,首先调用的是基类中的构造函数,然后才是调用派生类自己的构造函数...而在析构的时候,顺序则刚好相反,先调用派生类的析构函数,然后才是调用基类的构造函数。这是由于对象创建时候对象存放在堆栈中的原因。(new 的对象尽管是存在堆中,可是在堆栈中依旧存放其堆中的地址,因此。

1.1K10

从零开始学C++之继承(二):继承与构造函数、派生类到基类的转换

一、不能自动继承的成员函数 构造函数(包括拷贝构造函数) 析构函数 =运算符 二、继承与构造函数 基类的构造函数不被继承,派生类中需要声明自己的构造函数。...声明构造函数时,只需要对本类中新增成员进行初始化,对继承来的基类成员的初始化调用基类构造函数完成(如果没有给出则默认调用默认构造函数)。...从输出可以看出: 派生类对象的构造次序: 先调用基类对象成员的构造函数,接着是基类的构造函数,然后是派生类的对象成员的构造函数,最后是派生类自身的构造函数。...初始化列表参数多个且其中有调用基类构造函数时,先执行基类构造函数(从最远的开始,如果多重继承则按继承的顺序);其他对象成员若不止一个,则按定义的顺序构造,与初始化列表顺序无关。...向下转型不安全,没有自动转换的机制 // 从语法上来演示基类对象可以转化为派生类对象,但是没有意义 1、转换构造函数: Manager(const Employee& other) : Employee

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

    面向对象编程:继承从理论到实战

    我们一一来看~ 4.1.1 构造 在派生类中,我们不写构造,编译器自动生成的构造函数对于基类中的那一部分成员必须调用基类中的构造函数去初始化基类的那一部分成员,如果基类中没有默认的构造函数,则必须在派生类构造函数的初始化列表中显示调用...4.1.2 拷贝构造 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。...对于拷贝构造而言,派生类中不写,编译器自动生成的拷贝构造就够用了 但是如果有需要深拷贝的成员,就需要我们自己写一个~ 为什么这里可以这么写:Person(s)?...,我们就可以来看看上面学习的派生类可以给基类 派生类对象赋值给基类对象是通过基类的拷贝构造函数或者赋值重载函数完成的 4.1.4 析构 在派生类中,我们不显示写析构,编译器会自动生成一个,对派生类中的基类那一部分会去调用基类的析构...为什么这里会打印两次析构? ok,这是因为调用了两次析构,其实这里不用显示调用基类析构,编译器会在派生类析构结束后,自动调用基类析构。

    18110

    当类构造与析构的时候...

    关于虚函数部分不在这篇再提,上一篇提过了。 文章目录 什么时候会调用默认构造函数 什么时候调用拷贝构造函数? 什么时候调用赋值运算符? 深拷贝与浅拷贝 成员初始化列表的概念,为什么用它会快一些?...C++中struct和class的区别 什么时候会调用默认构造函数 1、当不使用任何初始值定义一个类的非静态变量时,会调用该类的默认构造函数。...1、初始化一个const成员 2、调用基类构造函数时的传参 3、初始化不存在默认构造函数的别的类的对象 ---- 构造/析构函数的执行顺序 构造的时候:如果基类,先调用基类的构造函数,再调用自己的构造函数...析构的时候,如果有基类,且基类的析构函数是虚函数,则先调用自己的构造函数,再调用基类的构造函数。 如果基类的析构函数不是虚函数,则调用基类的析构函数。 ---- 继承机制中对象之间如何转换?...向下类型转换 将基类指针或引用转换为派生类指针或引用被称为向下类型转换,向下类型转换不会自动进行,因为一个基类对应几个派生类,所以向下类型转换时不知道对应哪个派生类,所以在向下类型转换时必须加动态类型识别技术

    89220

    【C++ 进阶】继承

    但是必须是基类的指针是指向派生类对象时才是安全的; 四.隐藏(重定义) 1.子类和父类中,只要函数名相同就构成隐藏; 2.成员名相同也构成隐藏; 3.在子类成员函数中,可以使用 基类::基类成员...五.派生类中的默认成员函数 1.构造函数  派生类必须先自动调用基类的默认构造(初始化基类的那一部分成员),如果基类没有默     认构造,就要在派生类的初始化列表阶段显式调用基类的构造函数,然后派生类调用自己...2.拷贝构造    派生类的拷贝构造必须先调用基类的拷贝构造完成基类的拷贝初始化。 3.赋值重载    派生类赋值重载必须先调用基类的赋值重载完成基类的复制。...4.析构函数    销毁对象时,会先调用派生类的析构函数,然后再自动调用基类的析构函数,这样就保证     了析构的顺序(即先子后父);    如果不是这个顺序,一个成员可能会析构两次,就会导致程序崩溃...,在调用完后,编译器又会自动调用一次父类的析构函数, //导致父类成员_a析构了两次,从而程序崩溃 } int* _b = new int; }; int

    30210

    C++ 继承入门:从基础概念到默认成员函数,吃透类复用的核心逻辑

    子类对象 → 父类对象(调用父类拷贝构造,只拷贝父类部分) // 派生类对象可以赋值给基类的对象是通过调用后面会讲解的基类的拷⻉构造完成的 Person pobj = sobj; //3....默认生成的构造,派生类自己的成员,内置类型不确定,自定义类型调用默认构造,基类部分调用默认构造 本质可以把派生类当做一个自定义成员变量(基类)的普通类总,跟普通类原则基本一样 派生类一般要自己实现构造,...派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。...派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。...4.5 实现一个不能被继承的类 方法一:基类的构造函数私有,派生类的构成必须调用基类的构造函数,但是基类的构成函数私有化以后,派生类看不见就不能调用了,那么派生类就无法实例化出对象。

    23010

    继承

    派生类是可以给基类赋值的,可以是赋值给基类的指针,基类的引用,基类的对象。...如果基类中有默认成员函数,当派生类中不显示调用的时候,会自动调用。 对于构造函数,都会在初始化列表的时候自动调用基类的构造函数。...对于析构函数,在对象销毁的时候,会自动调用基类的析构函数,在调用自身的析构函数,所以,不需要自己在析构函数里面显示的调用基类的析构函数。...这样才能保证先析构派生类,再析构基类 构造函数 1.当基类有默认的构造函数的时候,可以只初始化派生类新的成员变量,也可以自己调用基类的默认构造,看自己的心情。...2.当基类没有默认的构造函数的时候,必须自己要写构造函数调用基类的 派生类的构造函数先初始化基类,再初始派生类中的成员 静态成员变量不属于具体的类对象,属于该类所有对象。

    50140

    C++~~期末复习题目讲解---lijiajia版本

    ; 创建基类对象obj1,创建派生类对象obj2和obj3,然后去调用函数,第一次调用func函数传递基类对象的地址,打印的就是base class,第二次调用这个函数,虽然传递的是派生类对象的地址,但是...b,和基类的指针p指向派生类D,使用这个D创建对象d,然后依次调用这个函数,第一个函数的参数就是基类指针,第二个函数的参数就是基类的引用,第三个函数的参数就是派生类的对象; 首先我们主函数里面调用第一个函数...,传递的参数就是p指针,也就是基类的指针,这个基类的指针可以访问到派生类里面的成员函数,因为我们创建一个派生类D,指针指向他;(基类的指针指向派生类的对象的地址) 第二次调用函数,参数是对象的引用,而且是基类对象的引用...; (2)虚函数的第二个题目 这个基类里面有一个虚函数,一个不是虚函数; obj这个派生类的对象,函数参数是基类的引用,调用fun1函数,只会访问这个基类的成员函数,调用fun2就会访问这个派生类里面的函数...,所以只会打印一个2,就是第二个2; 然后基类的指针p指向派生类对象cc,调用f函数的时候,先调用父类的f函数,输出1,再输出3; (4)虚函数的第四个问题 我们创建了一个基类的对象,fn传参,形参是基类的引用

    19300

    C++笔记-继承(下)(包含派生类的默认成员函数,菱形继承等)

    1.派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表显示调用。...2.派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。 3.派生类的operator=必须要调用基类的operator=完成基类的复制。...因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。 5.派生类对象初始化先调用基类构造再调派生类构造。 6.派生类对象析构清理先调用派生类析构再调基类的析构。...接下来呢时拷贝构造函数,这类有人可能有疑惑:为什么直接传s就可以呢?...4.2实现一个不能被继承的类 不能被继承的方式我讲解两种:c++98和c++11两种不同的方式。 c++98的方法就是将父类的构造函数放在private下,这种方式为什么可以呢?

    10110

    c++类和继承面试点25连问

    ,先调用基类的构造函数,再调用派生类的构造函数; 派生类对象销毁时,先调用派生类的析构函数,再调用基类的析构函数。...运行时多态简单来讲就是:使用基类指针或者引用指向一个派生类对象,在非虚继承的情况下,派生类直接继承基类的虚表指针,然后使用派生类的虚函数去覆盖基类的虚函数,这样派生类对象通过虚表指针访问到的虚函数就是派生类的虚函数了...因为销毁的时候直接销毁的基类指针,此时编译器只知道调用基类析构,并不会主动去调用派生类的析构函数,所以基类析构函数需为虚析构函数,这样运行时程序才会去调用派生类的析构函数,其实这就相当于析构函数的多态,...基于多态的作用,这个指向派生类的基类指针会先调用派生类的析构函数,然后再调用基类的析构函数。...的构造函数和析构函数都执行了两次,这很显然是不正确的,因为执行类B构造函数时要执行一次类A的构造函数,执行类C的时候也要执行一次类A的构造函数,析构函数同理,到这里问题还不大,毕竟可以编译和运行。

    1.3K10

    【C++:继承】面向对象编程精要:C++继承机制深度解析与最佳实践

    4.2 成员函数生成的核心机制 1、派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。...2、派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。 3、派生类的operator=必须要调用基类的operator=完成基类的复制。...因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。 5、派生类对象初始化先调用基类构造再调派生类构造。 6、派生类对象析构清理先调用派生类析构再调基类的析构。...(整体对象)+ 自己的成员变量(遵循普通的规则,跟类和对象部分一样)默认生成的构造,派生类自己的成员,内置类型不确定,自定义类型调用默认构造,基类部分调用默认构造本质上可以把派生类当做多了自定义类型成员变量...4.3.2 【关键问题】多态环境下的析构函数陷阱(不重写就会内存泄漏)——析构两次 运行一下,发现会析构两次—— 为什么会这样呢?

    23810

    【C++】从零开始认识继承

    但是我们写了一个基类Person的全缺省构造函数,这里就会在没有传参的时候没有默认构造函数匹配,这时派生类Student就会报错: 为了避免这样的错误,我们可以增添派生类Student的构造函数...对于以后多态的需要,一般析构函数名都会统一处理为destructor 想要调用就标明作用域:Person::~Person(),但是像上述这样写,会有一个问题,基类的析构会调用两次!!!...总结 派生类的默认成员函数的注意事项: 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。...派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。 派生类的operator=必须要调用基类的operator=完成基类的复制。...派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。 派生类对象初始化先调用基类构造再调派生类构造。

    32110

    【C++修炼之路】15.C++继承

    _name; // 姓名 }; 下面就开始探讨: 4.1 派生类的构造函数 派生类不写构造函数,不会报错: 如果将基类构造函数去掉,派生类不写默认成员函数就会报错,因为派生类调用的是父类的构造函数。...发现顺序: 构造: 基类先构造,派生类后构造。 析构: 派生类先析构,基类后析构。 4.5 总结 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。...如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。...派生类的operator=必须要调用基类的operator=完成基类的复制。 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。...因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。 派生类对象初始化先调用基类构造再调派生类构造。 派生类对象析构清理先调用派生类析构再调基类的析构。

    76500

    初识C++ · 多态(1)

    第一,参数明明是Person的引用,为什么传Student也可以,这里就用到了继承的切片的概念,基类不可以赋值给派生类,但是派生类可以赋值给基类,因为派生类赋值给基类的时候可以切片,即切除了派生类的元素...所以现在可以得出多态实现的两个条件,第一个是必须通过基类的指针或者引用来调用虚函数, 第二个是调用的函数必须是虚函数,而且是在派生类中进行重写了的。 那么,什么是虚函数和重写?...但是呢,重写也是有例外的,如下: i) 协变 协变就是基类和派生类的函数都满足虚函数和重写的定义,但是返回值不同,基类的返回值返回的是基类的指针,派生类的返回值返回的是派生类的指针,返回的指针的基类或者是派生类可以不是该基类或者是该派生类...这里呢,再提及一个点就是,对于虚函数来说,基类函数加了virtual,派生类函数可以不用加了,但是这个习惯其实不太好,感觉代码可读性下降了一点? 所以这里不做过多强调。...第二种,我们将构造函数变为私有的,这样就可以防止类被继承了,因为派生类构造的时候也会调用基类的构造,这里变为私有的就构造不了了,这种方法的思路挺厉害的: class A { private: A()

    24610

    创建子类对象时,父类构造函数中调用被子类重写的方法为什么调用的是子类的方法?

    public static void main(String[] args) { A a = new A(); B b = new B(); } } 问题:为什么创建...A对象的时候父类会调用子类方法?...但是:创建B对象父类会调用父类的方法? 答案: 当子类被加载到内存方法区后,会继续加载父类到内存中。...如果子类方法没有重写也没有重载父类方法,则方法引用会指向父类方法。 当子类对象创建时,会先行调用父类的构造方法(构造方法也是方法),虚拟机会在子类方法区寻找该方法并运行。...其结果是当编译的时候,父类构造方法调用的方法的参数已经强制转换为符合父类方法的参数了。 上边代码在编译前已经转换为下面这个样子的了。

    9.5K10

    【C++高级主题】虚基类的声明

    二、虚基类的核心特性解析 2.1 支持到基类的常规转换 在虚继承中,指向派生类的指针或引用可以隐式转换为指向虚基类的指针或引用,且这种转换是唯一的(因为虚基类在最终派生类中只存在一个实例)。...2.3 虚基类的特殊初始化语义 虚基类的初始化规则与普通继承有本质区别:虚基类的构造函数由最终派生类直接调用,中间派生类对虚基类的构造函数调用会被忽略。...①规则详解 在普通继承中,派生类的构造函数会调用直接基类的构造函数,形成 “基类→派生类” 的构造链。...; 如果最终派生类未显式调用虚基类的构造函数,则使用虚基类的默认构造函数(若不存在默认构造函数则编译报错)。...4.2 为什么需要虚基类表? 在普通继承中,基类的位置是固定的(相对于派生类对象的起始地址),因此可以在编译时确定基类成员的访问地址。

    17210

    【C++ 继承】—— 青花分水、和而不同,继承中的“明明德”与“止于至善”

    派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显式调用基类的构造函数。...派生类的拷贝构造函数必须调用基类的拷贝构造函数完成基类的拷贝初始化。 派生类的 operator= 必须调用基类的 operator= 完成基类的复制。...派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。这是为了保证派生类对象先清理派生类成员、再清理基类成员的顺序。 派生类对象初始化时,先调用基类构造函数,再调用派生类构造函数。...默认构造函数 (Derived() = default;) 基类构造规则: 自动调用 基类的默认构造函数。 若基类无默认构造函数,必须显式调用基类的其他构造函数。...从下面的对象成员模型构造可以看出,菱形继承存在数据冗余和二义性的问题。 单继承 定义 一个派生类(Derived Class)只有一个直接基类(Base Class)的继承关系。

    70810

    C++基础(七).多态(1)

    虚函数必须是类的非静态成员函数(且非构造函数),其访问权限是public 虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数进行重新定义...如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数 虚函数可以让成员函数操作一般化,用基类的指针指向不同的派生类的对象时,基类虚成员函数调用基类指针,则会调用其真正指向的对象的成员函数,而不是基类中定义的成员函数...若不是虚函数,则不管基类指针指向哪个派生类对象,调用时都会调用基类中定义的那个函数 Tip: 虚函数的引入就是为了实现多态的特性,让不同的子类可以有不同的实现方式 ---- 纯虚函数 纯虚函数是一种特殊的虚函数...如果派生类中给出了基类纯虚函数的实现,则该派生类就不再是抽象类了,它是一个可以建立对象的具体类了 抽象类中,既可以有抽象方法,也可以有具体方法或者叫非抽象方法。...比如类B虚继承于类A,那类A就称作类B的虚基类,如果没有虚继承,那类B就只是类A的基类 虚继承主要用于一个类继承多个类的情况,避免重复继承同一个类两次或多次 例如 由类A派生类B和类C,类D又同时继承类

    71220

    C++继承

    调试发现,学生类和教师类创建的对象中有信息类的成员和成员函数。 定义 这里来说说定义的格式: 派生类也可以叫子类,基类也可以叫做父类。...,_num(num) { } protected: int _num;//学号 }; int main() { Student s("baiye",18); return 0; } 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员...如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。 拷贝构造: 因为都是内置类型,如果是子类的成员就调用子类的默认拷贝构造,父类的成员就去调用父类的拷贝构造。...那么如果遇到深拷贝的时候,子类就必须去写构造函数了。 在初始化列表中调用父类的拷贝构造就可以了。 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。...因为这里子类析构调用完之后又回去调用父类析构,这是编译器的默认行为。 也就是说我们根本不用去显示的调用父类的析构函数。 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。

    87310
    领券