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

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

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

6.2K10

代码重用

,就可以将基类指针或引用指向派生类对象) 3....从本质上讲,应该是继承的BaseA和BaseB类对象共享了一个Base对象。这样就可以简单的使用多态。 针对虚基类,在设计的时候需要对其类构造函数采用一种新的方法。...因此上述ba的信息必不能传递给子对象Base,然而编译器会使用Base的默认构造函数,在构造派生类对象之前构造基类对象组件。如果不希望使用默认构造函数来构造虚基类函对象,则需要显式地调用基类构造函数。...abc){} (注:上述代码显式地调用Base的构造函数,是合法的,但是对于非虚基类,则是非法的。)...如果类有间接虚基类,则除非只使用该虚基类的默认构造函数,否则必须显式地调用该虚基类的某个构造函数。

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

    【C++进阶】多态的理解

    一.多态是什么 多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。 对于多态,不同的对象传过去,会调用不同的函数; 即多态调用看的是指向的对象。...例外:              a.派生类可以不加 virtual  ,因为派生类已经继承了基类的 virtual;              b.协变(基类虚函数返回基类对象的指针或者引用,派生类虚函数返回派生类对象...结论 析构函数建议设置成虚函数,因为有时可能利用多态方式通过基类指针调用子类析构函        数,尤其是父类的析构函数强力建议设置为虚函数,这样动态释放父类指针所指的子类      对象时,能够达到析构的多态...虚表生成 虚表指针其实是在初始化列表阶段初始化的,所以构造函数不能设置成虚函数; 虚表生成:                   a.先将基类中的虚表内容拷贝一份到派生类虚表中 ;                  ...b.如果派生类重写了基类中某个虚函数,用派生类自己的虚函数覆盖虚表中基类的虚函                       数;                   c.派生类自己新增加的虚函数按其在派生类中的声明次序增加到派生类虚表的最后

    12110

    《C++Primer》第十五章 面向对象程序设计

    :一种是基类希望其派生函类进行覆盖的函数,另一种是基类希望派生类直接继承而不要改变的函数。...,派生类必须使用基类的个构造函数来初始化它的基类部分。...如果想使用其他的基类构造函数,我们需要以类名加圆括号内的实参列表的形式为构造函数提供初始值。这些实参用于帮助编译器到底应该选择哪个构造函数来初始化派生类对象的基类部分。...,但是Disc_quote的派生类构造函数会使用Disc_quote的构造函数来构建各个派生类对象的Disc_quote部分。...含有纯虚函数的类是抽象基类 抽象基类负责定义接口,而后续的其他类可以覆盖接口。我们不能(直接)创建一个抽象基类的对象。

    1.2K20

    C++面向对象编程一些拾遗

    派生类构造前,会先调用基类的构造函数来构造继承来的成员,当一个派生类有多个基类时,那么按照类定义的时候的继承顺序来依次调用基类的构造函数。...总的来说: 执行基类的构造函数,当有多个基类时,按照类定义时的继承顺序来。 执行成员对象的构造函数,当类有成员是对象时,构造完基类后,会调用成员对象的构造函数进行构造。 执行派生类的构造函数。...派生类的析构函数。 和对象构造的时候刚好是相反的顺序。 对派生类的新增普通成员进行清理。 调用成员对象的析构函数。 调用基类析构函数。 十.继承和虚函数。 1. 覆盖基类的函数。...虚拷贝构造函数(虚复制构造函数) 由于构造函数不能是虚的,但是在某些需求下:需要通过传入一个指向基类指针(可以指向派生类对象)来获取派生类的拷贝,这个时候就需要自己定义一个虚的clone()函数来实现这种需求...//鸟 也就是说,中间类(我就这样做吧),不会去调用基类的构造函数来构造基类(因为是虚继承的),最终的派生类会调用基类的构造函数来构造基类,所以在派生类的构造函数上要加上基类的构造函数!

    70120

    总结继承和多态的一些问题

    2.区分虚表和虚表指针生成阶段 虚表是在编译阶段就生成的了,而虚表指针是在构造函数初始化列表阶段初始化的。这也侧面回答了下一个问题。 3.构造函可以是虚函数吗?...不行的,因为对象中的虚函数表指针是在构造函数初始化列表阶段才初始化的。 4.区分切片和派生类虚表的生成 先来说派生类生成虚表的步骤: ①先是继承了基类的虚表,是把基类的虚表拷贝下来了。...切片: 我们都知道,多态的的条件是虚函数的重写和必须通过基类的指针或者引用调用虚函数。。那么为什么一定是需要基类的指针或引用呢? 先来看看不用指针或引用,也就是使用基类对象来调用虚函数。...因此,简单的总结就是:派生类对象赋值给基类对象,切片会把派生类中包含的基类成员变量的值拷贝过去,但是派生类的虚表不会给拷贝过去,则函数中这个基类对象的虚表是基类的,所以无法实现多态。...因为有时候我们难免会用基类指针或引用指向派生类对象,基类的析构函数是虚函数的话,可以准确地调用派生类的析构函数。 8.对象访问普通函数快还是虚函数更快? 首先如果是普通对象,是一样快的。

    45720

    移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——11.多态

    协变(基类与派生类虚函数返回值类型不同) 派生类重写基类虚函数时,与基类虚函数返回值类型不同。即基类虚函数返回基类对象的指 针或者引用,派生类虚函数返回派生类对象的指针或者引用时,称为协变。...如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字, 都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同。...Student的析构函数重写了Person的析构函数,下面的delete对象调用析构函 数,才能构成多态,才能保证p1和p2指向的对象正确的调用析构函数。...静态成员可以是虚函数吗? 答:不能,因为静态成员函数没有this指针,使用类型::成员函数 的调用方式无法访问虚函数表,所以静态成员函数无法放进虚函数表。 6. 构造函数可以是虚函数吗?...如果是指针 对象或者是引用对象,则调用的普通函数快,因为构成多态,运行时调用虚函数需要到虚函 数表中去查找。 9. 虚函数表是在什么阶段生成的,存在哪的?

    8710

    图解python | 面向对象编程

    继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。...例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。 实例化:创建一个类的实例,类的具体对象。...相比其它编程语言,Python的类机制非常简洁,Python中的类提供了面向对象编程的所有基本功能 类的继承机制允许多个基类 派生类可以覆盖基类中的任何方法 方法中可以调用基类中的同名方法 对象可以包含任意数量和类型的数据... 类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性。 4.类对象 [创建类对象] (1)属性引用和实例化 类对象支持两种操作:属性引用和实例化。... 子类(派生类/DerivedClass)会继承父类(基类/BaseClass)的属性和方法。 BaseClassName(实例中的基类名)必须与派生类定义在一个作用域内。

    61241

    C++终结类

    由于任何派生类的对象在创建的时候,都必需在派生类的构造函数中调用父类的构造函数。所以,只要类的构造函数在子类中无法被访问,那么就阻止了该类被继承,实现终结类。...如果将一个类的构造函数声明为私有(private),可以阻止该类进一步派生,但是该类也无法直接实例化了,此方法行不通。注意,构造函数为private的类,无法直接实例化,但是可以被间接实例化。...间接实例化方法是:类中定义一个公有的静态成员函数,由这个函数来完成对象的初始化工作。...一个基类如果被虚拟继承,那么在创建它的孙子类的对象时,该基类的构造函数需要单独被调用。此时,如果该基类的构造函数在孙子类的构造函数中无法访问,那么就实现了基类的子类不能被继承。...利用虚拟继承的这种特性,我们可以设计出这样一个基类FinalParent,它不定义任何数据成员,这样任何类从它派生并不会增加任何空间上的开销。

    52020

    C++实现不能被继承的类——终结类

    但从C++11开始,提出了final关键字来申明终结类。 2.       解决方法 基本思路:由于任何派生类的对象在创建的时候,都必需在派生类的构造函数中调用父类的构造函数。...所以,只要类的构造函数在子类中无法被访问,那么就阻止了该类被继承,实现终结类。 如果将一个类的构造函数声明为私有(private),可以阻止该类进一步派生,但是该类也无法直接实例化了,此方法行不通。...注意,构造函数为private的类,无法直接实例化,但是可以被间接实例化。间接实例化方法是:类中定义一个公有的静态成员函数,由这个函数来完成对象的初始化工作。...一个基类如果被虚拟继承,那么在创建它的孙子类的对象时,该基类的构造函数需要单独被调用。此时,如果该基类的构造函数在孙子类的构造函数中无法访问,那么就实现了基类的子类不能被继承。...利用虚拟继承的这种特性,我们可以设计出这样一个基类FinalParent,它不定义任何数据成员,这样任何类从它派生并不会增加任何空间上的开销。

    1.8K30

    十、继承

    注意访问权限:在继承时,要注意基类成员的访问权限,确保派生类能够访问到需要的成员。 构造函数和析构函数:派生类的构造函数需要调用基类的构造函数来初始化继承来的成员。...public 继承使得基类的 public 和 protected 成员在派生类中保持原有的访问级别。 使用派生类的对象 最后,我们可以通过创建派生类的对象并使用它来访问基类和派生类的成员。...构造函数和析构函数: 构造函数和析构函数不能继承,但派生类可以定义自己的构造函数和析构函数来执行必要的初始化或清理工作。 派生类构造函数可以通过成员初始化列表显式地调用基类的构造函数。...构造函数 构造函数是特殊的成员函数,用于在对象创建时初始化对象。 基类的构造函数:在创建派生类对象时,首先会调用基类的构造函数(如果有的话)。...如果基类有多个构造函数,派生类构造函数可以通过初始化列表来指定使用哪一个。 派生类的构造函数:派生类的构造函数可以初始化派生类特有的成员变量,并且可以通过初始化列表来调用基类的构造函数。

    7710

    《Effective C++》读书笔记(二):构造析构赋值运算(条款05~条款12)

    () { Corgi co; return 0; } 分析代码: 代码中,用派生类创建了一个派生类的对象,在构造函数被调用的时候,会先去构造基类的成分,然后才会去构造派生类的从成分,这就意味着,会先去调用基类的构造函数...基类的构造函数最后会去执行count_Dog函数,问题就出现在这里,上面说了,构造函数构造期间,基类的virtual函数不会下降到派生类中,也就是说即使我们创建的对象属于派生类的,但是在调用基类的构造函数期间...这种现象根本的原因在于:在派生类对象调用基类的构造函数期间,由于是基类先构造,那么在此期间,此时的对象被视为是基类的对象,并且派生类的成分并没有初始化,因此C++的做法是视它们不存在,这样才能保证安全。...,通过调用了createdogs函数,创建了基类Dog的匿名对象,也就是调用了基类的构造函数,然后进入了count_Dog函数,最后再次去调用派生类的构造函数的主体!...,正是因为派生类的成员变量没有初始化,所以在基类的构造和析构期间调用的virtual函数不可以下降到派生类阶层。

    37010

    【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)

    继承允许我们在原有的类的基础之上进行扩展,创建一个新的类(叫做子类或派生类),该类可以继承原有类(叫做父类或基类)的属性和方法。继承体现了面向对象编程的层次结构--从简单到复杂的过程。...A n = m;//派生类对象赋给基类对象,通过调用基类的拷贝构造来完成 A* p = &m;//派生类的指针赋给基类的指针 A& r = m;//派生类对象赋给基类的引用 return...派生类的构造函数需要先调用基类的构造函数来初始化基类部分的成员,然后再初始化自己的成员。如果基类没有默认构造函数,则需要通过初始化列表传参构造,否则会发生编译报错。 2....与构造函数相同,派生类的拷贝构造函数也需要先调用基类的拷贝构造函数来初始化基类部分的成员。 3. 派生类的赋值重载需要调用基类的赋值重载来完成基类部分的拷贝赋值。...那么我们是否可以利用这一规则,来实现一个不能被继承的类呢? 方法1:将基类的构造函数设置为私有成员,那么派生类就无法调用基类的构造函数,无法实例化出对象。

    24410

    C++之多态

    协变(基类与派生类虚函数返回值类型不同) 派生类重写基类虚函数时,与基类虚函数返回值类型不同。即基类虚函数返回基类对象的指 针或者引用,派生类虚函数返回派生类对象的指针或者引用时,称为协变。...(基类析构函数和派生类析构函数的函数名不同) 如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字, 都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同。...Student的析构函数重写了Person的析构函数,下面的delete对象调用析构函 //数,才能构成多态,才能保证p1和p2指向的对象正确的调用析构函数。...• 只有类的成员函数才能声明为虚函数 • 虚函数不能是静态成员函数 • 虚函数不能是友元函数 • 若在基类中定义虚函数,在派生类中需要重新定义 • 构造函数不能是虚函数 • 析构函数可以是虚函数...,派生类继承了基类函数,可以使用函数,继承的是函数的实现。

    7810

    C++设计类的注意事项

    构造函数 如果没有声明构造函数,编译器会定义一个默认构造函数(无参数、无内容),让你可以不初始化来直接创建对象: Star rigel; Star pleiades[6]; 但如果定义了某种形式的构造函数...构造函数用来创建新对象,它是不能被派生类继承的,派生类需要定义自己的构造函数,并在初始化列表中调用基类的构造函数: SubClass::SubClass(int a, int b):BaseClass(...//注意这个函数的参数应该是基类引用,但是基类引用是可以指向子类的,它只会操作基类的成员 ...// 操作派生类的成员 return *this; } 析构函数 一定要注意显式定义析构函数来释放构造函数使用...虚函数的意义是当用基类的指针或引用指向对象时(不管指向的是基类对象还是派生类对象),调用虚函数会根据对象真实类型调用对应方法。...,比如有一个类是“圆形类”,一个类是“椭圆形类”,为了方便可以定义一个“形状类”作为它们两个的抽象基类,持有一些比如圆心坐标等的共有成员和方法,但是你不能去创建一个“形状”对象来,没什么意义。

    39920

    【C++高阶】多态(概念&&虚函数&&抽象类)

    (基类与派生类析构函数的名字不同) 如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同。...1、让编译器帮助用户检测是否派生类是否对基类总的某个虚函数进行重写,如果重写成功,编译通过,否则编译失败,因此其作用发生在编译时。...派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象 2.2 接口继承和实现继承 普通函数的继承是一种实现继承,派生类继承了基类函数,可以使用函数,继承的是函数的实现。...基类和派生类不会共用一张虚函数表,而是会依据基类自己构造来避免调用不明的问题 b. 同一个自定义类型的对象将会共用一张虚函数表 c....,找到不同的虚函数来调用, 这样就实现出了不同对象去完成同一行为时,展现出不同的形态 因此我们可以看出满足多态以后的函数调用,不是在编译时确定的,是运行起来以后到对象的中取找的。

    17010

    【笔记】《C++Primer》—— 第三部分:类设计者的工具

    13 拷贝控制 拷贝构造函数会自动将每个非static成员依次拷贝到正在创建的对象中,其中内置类型会直接拷贝,数组会被逐元素地拷贝,类类型会调用拷贝构造函数来拷贝 如果初始化值要求一个explicit...=&inp)来检测是否发生自赋值,若发生则不要进行内部的控制权转移部分 移动后的源对象必须保证是有效且可安全析构的状态,而且不能假设这个源对象的任何值 一个类可以既有移动拷贝也有拷贝构造,此时编译器将会进行最佳匹配...我们很多时候希望的是我们通过将基类指针指向派生类,然后可以动态调用派生类的函数,这时我们可以将基类的对应函数写为虚(virtual)函数来实现,此时发生的称为动态绑定 派生类可以继承多个基类,称为多继承...每次继承一个基类就会在内存中生成一个子对象,存放了基类的成员,也正是因为这个原因派生类可以转换为基类 派生类的构造函数需要负责所有成员的初始化,尽管派生类也可以初始化继承来的基类成员,但是这不符合通常的编码思路...,派生类一般在构造函数开始的地方调用基类的构造函数,让基类来初始化自己的成员 静态类型是变量本身代码中的类型,在编译时决定,动态类型是变量在内存中的对象的类型,在运行时才能决定。

    1.7K10

    第 15 章 面向对象程序设计

    派生类应该遵循基类的接口,通过调用基类的构造函数来初始化那些从基类中继承而来的成员。派生类的初始化过程大致为:基类初始化——>基类构造函数体——>派生类初始化——>派生类构造函数体。...一个基类的对象既可以以独立的形式存在,也可以作为派生类对象的一部分存在。因此基类不一定是派生类对象的一部分,但派生类中一定含有基类部分。...含有纯虚函数的类是抽象基类。抽象积累负责定义接口,而后续的其他类可以覆盖该接口。不能(直接)创建一个抽象基类的对象,但派生类构造函数可以使用抽象基类的构造函数来构建各个派生类对象的基类部分。...---- 15.7 构造函数与拷贝控制 当需要 delete一个的基类指针时,该指既可以指向基类对象,也可以指向派生类对象,此时编译器必须明确执行基类或派生类的指针。...通过一条注明了(直接)基类名的 using声明语句,派生类可以从基类继承构造函数。

    1K30

    EasyC++79,虚函数注意事项

    这里简单做一个总结: 在基类的方法声明中使用关键字virtual可以声明虚函数 加上了virtual关键字的函数在基类以及派生类和派生类再派生出来的类中都是虚的 在调用虚函数时,程序将会根据对象的类型执行对应的方法而非引用或指针的类型...构造函数 构造函数不能是虚函数,创建派生类对象时将调用派生类的构造函数,而非基类的构造函数,毕竟构造函数是根据类名调用的。...一般我们会在派生类中调用基类的构造函数,这其实不是继承机制,所以将类构造函数声明为虚没有意义。 析构函数 前文说过析构函数应该是虚函数,除非类不被继承。...因为派生类当中往往含有独有的成员变量,如果析构函数非虚,那么会导致在对象析构时仅调用基类的析构函数,从而导致独有的成员变量内存不被释放,引起内存泄漏。...C++ Primer当中给出了两条经验规则: 如果重新定义继承的方法,应该保证与原来的原型完全相同,唯一的例外是返回的类型,如果基类返回的是基类的引用或指针,派生类可以改成派生类的引用或指针: class

    23210

    【笔记】《C++Primer》—— 第15章:面向对象程序设计

    我们很多时候希望的是我们通过将基类指针指向派生类,然后可以动态调用派生类的函数,这时我们可以将基类的对应函数写为虚(virtual)函数来实现,此时发生的称为动态绑定 基类通过在声明语句前加上关键字virtual...如果是指针或引用的转换,则只是一个指向的改变 派生类的构造函数需要负责所有成员的初始化,尽管派生类也可以初始化继承来的基类成员,但是这不符合通常的编码思路,派生类一般在构造函数开始的地方调用基类的构造函数...15.4 抽象基类 我们有时候希望某个基类只用来被继承而不允许被实例化,这时候我们可以给这个基类加入纯虚函数,拥有纯虚函数的基类叫抽象基类,不能被直接创建 纯虚函数的定义方法是在声明函数名的时候函数体类似显式默认构造的写法改写为...,目标的静态类型决定了其是否可见 和其他作用域一样,派生类可以重用基类中的名字,因此当名字重叠时派生类的名字会隐藏基类中的名字,类似函数中的情形。...因此通常我们定义派生类的拷贝构造函数时也会在列表里调用基类的拷贝构造函数。其他操作也有类似的设计 对象销毁的顺序与构造的顺序正好相反,派生类的析构先执行然后是基类,派生类的构造先构造基类再构造派生。

    53320
    领券