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

在基类构造函数中调用虚方法

在基类构造函数中调用虚方法是一个常见的问题,因为基类构造函数在派生类构造函数之前执行,这意味着在基类构造函数中调用的虚方法将调用基类的实现,而不是派生类的实现。这可能会导致意外的行为和错误。

为了避免这个问题,可以采用以下方法:

  1. 在基类中使用一个虚方法,该方法在基类构造函数中被调用,并在派生类中重写该方法。这样,在基类构造函数中调用该方法时,将会调用派生类的实现。
  2. 在基类中使用一个抽象方法,该方法在基类构造函数中被调用,并在派生类中实现该方法。这样,在基类构造函数中调用该方法时,将会调用派生类的实现。
  3. 在基类中使用一个受保护的方法,该方法在基类构造函数中被调用,并在派生类中调用该方法。这样,在基类构造函数中调用该方法时,将会调用派生类的实现。

以上是一些常见的解决方案,可以避免在基类构造函数中调用虚方法的问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

禁止构造函数调用函数

构造函数调用函数会导致程序出现莫名其妙的行为,这主要是对象还没有完全构造完成。...这是因为构造函数调用一个定义本类的但是为派生所重写的函数,程序运行的时候会调用派生的版本,程序在运行期的类型是 A 而不是 B。... C# 系统会认为这个对象是一个可以正常使用的对象,这是因为程序进入构造函数函数体之前已经把该对象的所有成员变量都进行了初始化。...这么做主要是为了避免构造函数调用抽象方法,防止抛出异常。虽然这么写可以避免这个问题但是还存在一个很大的缺陷,它会造成 str 这个对象整个生命周期中无法保持恒定的值。...Tip:C# 对象的运行期类型是一开始就定好的,即便是抽象也依然可以调用其中的方法。 小结 构造函数调用函数会导致代码严重依赖于派生的实现,然后这些实现是无法控制且容易出错的。

1.6K20

#1构造函数调用方法 | TW洞见

谜题 C#,用virtual关键字修饰的方法(属性、事件)称为方法(属性、事件),表示该方法可以由派生重写(override)。...我们构造函数调用方法,碍着ReSharper什么事儿了? 其实这个警告就是提醒我们不要在非封闭类型的构造函数调用方法属性。但为什么这样做不合适呢?解惑之前,我们先来了解两个概念。...你也许已经猜到了,它的结果是: Base constructor Derived constructor 我们初始化一个对象时,总是会先执行构造函数,然后再执行子类的构造函数。...的构造函数调用方法V()时,ReSharper会给出virtual member call in constructor的警告。...Virtual member call in constructor的警告是因为,对于Base b = new Derived();这样的代码: 构造函数的执行要早于子类构造函数 构造函数对于方法调用

1.2K110

派生多态函数

C++语言中,必须将它的两种成员函数区分开来: 一种是希望其派生进行覆盖的函数 另一种是希望派生直接继承而不要改变的函数。 对于前者,通常将其定义为函数(virual)。...当我们使用指针或引用调用函数时,该调用将被动态绑定。...任何构造函数之外的非静态函数都可以是函数。 关键字virtual只能出现在内部的声明语句之前而不能用于外部的函数定义。 如果把一个函数声明成函数,则该函数派生也是函数。...成员函数如果没被声明为函数,则其解析过程发生在编译时而非运行时。就会按照实际情况调用。 派生可以继承定义的成员,但是派生的成员函数不一定有权访问从继承而来的成员。...如果派生没有覆盖其的某个函数,则该函数的行为类似于其他的普通成员,派生会直接继承其的版本,派生可以它覆盖的函数前使用virtual关键字,但不是非得这么做(可有可无)。

14720

c++继承 派生 函数

参考链接: C++继承 继承    的关系有组合、继承和代理。继承的本质就是代码复用。子类继承父的一些东西,父也称为,子类也称为派生。派生继承了构造函数以外的所有成员。 ...不同访问限定符下(public、protected、private)的成员以不同的继承方式继承,派生的访问限定也不同,具体如下:  的布局优先于派生  #include<iostream...1.调用构造函数 2.调用派生构造函数 派生的析构可想而知: 1.调用派生的析构函数 2.调用的析构函数  函数  如下程序:  class Base { public:     Base...中含有函数,那么布局存在一个函数指针,指向函数表;且其派生与其同名同参的函数不需要加virtual也是函数。...首先通过指针所指向的对象找到vfptr,再找到vftable,获取到Show函数的入口地址,此时 &Derive::Show存放的是派生函数入口地址,因此调用的是派生的Show()函数

1K20

派生函数和非虚函数的继承效果

,在编译阶段就确定好是被谁调用,所以他只认哪个指针指向自己,这里是Animal指针指向,所以他就调用Animal里面的,普通函数是父为子类提供的“强制实现”,也就是只要是父指针调用普通函数,那就是父的普通函数...而函数的作用,主要是为了让父指针可以调用子类的函数,这种是在运行时才决定调用哪个函数 1、函数:   C++的函数主要作用是“运行时多态”,父中提供函数的实现,为子类提供默认的函数实现。...子类可以重写父函数实现子类的特殊化。 2、纯函数:   C++包含纯函数,被称为是“抽象”。抽象不能使用new出对象,只有实现了这个纯函数的子类才能new出对象。   ...C++的纯函数更像是“只提供申明,没有实现”,是对子类的约束,是“接口继承”。   C++的纯函数也是一种“运行时多态”。...因此,继承关系,子类不应该重写父的普通函数,因为函数调用至于对象的字面值有关。 参考链接

2910

C++不要在构造函数和析构函数调用函数

虽然可以对函数进行实调用,但程序员编写函数的本意应该是实现动态联编。构造函数调用函数函数的入口地址是在编译时静态确定的,并未实现调用。...但是为什么构造函数调用函数,实际上没有发生动态联编呢? 1. 不要在构造函数调用函数的原因 第一个原因,概念上,构造函数的工作是为对象进行初始化。...当创建某个派生的对象时,如果在它的构造函数调用函数,那么此时派生构造函数并未执行,所调用函数可能操作还没有被初始化的成员,浙江导致灾难的发生。...B的对象b退出作用域时,会先调用B的析构函数,然后调用A的析构函数析构函数~A()调用函数show()。...从概念上说,析构函数是用来销毁一个对象的,销毁一个对象时,先调用该对象所属的析构函数,然后再调用的析构函数,所以,调用的析构函数时,派生对象的“善后”工作已经完成了,这个时候再调用在派生定义的函数版本已经没有意义了

2.7K30

构造函数和析构函数可以是函数吗,在里面能调用函数

先说构造函数构造函数作为函数是不可以的,首先c++编译器上不会让你通过 在内存上,我们知道,一个对象会有一个函数表,函数构造函数初始化,可是一个对象还没有完成实例化,他的函数表是不存在的...,一个对象需要调用构造函数完成实例化,这里形成了一个悖论 在意义上,将构造函数声明为函数没有意义,函数主要是实现多态,c++的多态是在运行时构建调用不同函数,而不是根据情况动态调用构造函数...这时候如果是指针指向子类对象,那么删除指针,只会调用的析构函数,因为这时候对象类型是对象,析构函数没有动态绑定,只会调用当前对象类型的析构。...那构造函数里能调用函数吗 这个问题之前腾讯后端一面出现过,我当时有点蒙 首先编译器是允许你这么做的,但是构造函数调用函数,可能达不到你想要的效果,我们看看下面的代码 class Father...//Father f 代码运行后,构造函数调用了父函数,我们本来想要调用子类的函数

1.2K50

菱形继承问题及解决方法继承与(C++)

m_Age,通过限定作用域的方式无法彻底解决这个问题,这个时候就要使用继承 继承与 具体实现为和驼的继承前加上virtual关键词,Animal称为 代码如下: #include... using namespace std; class Animal // { public: int m_Age; }; class Sheep :virtual public...,说明此时羊驼的m_Age只有一份 再次借助VS命令提示工具查看对象模型,运行结果如下: 画的有点凌乱.........可以看出羊和驼的数据只是一个指针,并未继承具体的数据,这个指针指向各自的表,而存在一个偏移量,通过这个偏移量再加上首地址可以找到的数据,所以实际上羊驼只继承了一份数据...(也就是的那份)。

1K40

C++ 构造函数与析构函数调用函数的注意事项

虽然可以对函数进行实调用,但程序员编写函数的本意应该是实现动态联编。构造函数调用函数函数的入口地址是在编译时静态确定的,并未实现调用。...但是为什么构造函数调用函数,实际上没有发生动态联编呢? 第一个原因,概念上,构造函数的工作是为对象进行初始化。构造函数完成之前,被构造的对象被认为“未完全生成”。...当创建某个派生的对象时,如果在它的构造函数调用函数,那么此时派生构造函数并未执行,所调用函数可能操作还没有被初始化的成员,将导致灾难的发生。...B的对象b退出作用域时,会先调用B的析构函数,然后调用A的析构函数析构函数~A()调用函数show()。...从概念上说,析构函数是用来销毁一个对象的,销毁一个对象时,先调用该对象所属的析构函数,然后再调用的析构函数,所以,调用的析构函数时,派生对象的“善后”工作已经完成了,这个时候再调用在派生定义的函数版本已经没有意义了

91510

面向Java对象和构造方法以及调用构造方法

软件对象的状态就是属性,行为通过方法体现。软件开发方法操作对象内部状态的改变,对象的相互调用也是通过方法来完成。 Java 可以看成是创建Java对象的模板。...通过下面一个简单的来理解下Java的定义: ? 一个可以包含以下类型变量: 局部变量:方法构造方法或者语句块定义的变量被称为局部变量。...成员变量可以被方法构造方法和特定的语句块访问。 变量:变量也声明方法体之外,但必须声明为static类型。...强调一遍:每个都有构造方法。如果没有显式地为定义构造方法,Java编译器将会为该类提供一个默认构造方法创建一个对象的时候,至少要调用一个构造方法。...构造方法的名称必须与类同名,一个可以有多个构造方法。 下面是一个构造方法示例: ? 创建对象 对象是根据创建的。Java,使用关键字new来创建一个新的对象。

1.1K10

C++核心准则C.82:不要在构造函数或析构函数调用函数

C.82: Don't call virtual functions in constructors and destructors C.82:不要在构造函数或析构函数调用函数 Reason...到目前为止,被调用函数应该只属于构造对象本身,而不是可能存在于派生的某个覆盖函数。那样做非常难理解。...最坏的情况,构造函数或者析构函数中直接或间接调用一个没有实现的纯函数会导致没有定义的行为。...从构造函数和析构函数调用函数并不是本身有什么错误。这种调用的语义是安全的。然而,经验表明这样的调用很少是必须的,很容易扰乱维护者,如果被新手使用会成为错误源。...提示来自构造函数或析构函数函数调用

74650

构造方法

1、构造方法概述 1.1、什么是构造方法 构造方法是正常开发不可或缺的一部分,是语法上必须存在的。是一个具有特殊格式的方法,且有特殊的调用方式。...1.2、构造方法作用 1.2.1、实例化对象 用来创建实例对象的方法,给对象的数据进行初始化,如: Person p = new Person(); 调用构造方法 Person();只是我们没有写这个方法...,抽象具有构造方法 构造方法不能被继承,如:父叫Person,子类叫Student 继承构造方法后,那么我new Person()后是子类的对象,还是父的对象,我们分不清楚 。...而且构造方法要求与名相同,那么子类里面的Person构造方法名冲突了 构造方法的public并不是固定不变的,可以使用其他格式修饰构造方法。...如:public、default、private 3.3、构造方法与set方法 构造方法是为了创建的同时直接为属性赋值。 set方法创建对象之后,再重新为成员变量赋值,是修改值的过程。

1K20

【C++】多态 ⑨ ( vptr 指针初始化问题 | 构造函数 调用 函数 - 没有多态效果 )

, 对象 被 创建时 , 由 C++ 编译器 对 对象的 vptr 指针进行初始化操作 , 对象 创建完成 后 , 也就是 函数 整理完毕 , 全部放到 函数后 , vptr 指针 才会指向...函数表 的首地址 ; 父 对象 的 vptr 指针 指向 父函数表 首地址 ; 子类 对象 的 vptr 指针 指向 子类 的 函数表 首地址 ; 3、构造函数 调用 函数 -... 调用 函数 , 则 没有 多态效果 ; 构造函数 , 调用了 父函数 ; 此时 , 如果 创建 子类对象 , 执行 父构造函数 , 仍然调用函数 , 子类的函数...父构造函数 调用 fun 函数 , 只能调用本身的 fun 函数 , 此时 vptr 指针没有指向 函数表 , 函数表未生效 , 只能调用的 fun 函数本身 ; 父构造函数...调用完毕后 , vptr 指针 才指向 父函数表 ; 然后 , 调用 子类 的构造函数 , 此时 子类构造函数 调用 fun 函数 , 只能调用 子类本身的 fun 函数 , 此时 vptr

22020

【C++ 语言】面向对象 ( 继承 | 重写 | 子类调用方法 | 静态多态 | 动态多态 | 函数 | 纯函数 )

文章目录 的继承 方法的重写 子类调用方法 多态 函数 函数示例 纯函数 相关代码 的继承 ---- 1....外部通过子类调用方法 : 如果调用方法子类没有重写 , 那么调用的就是父方法 ; //栈内存创建一个 Child 对象, 并调用其重写的父方法 Child child; //...函数解析 : 在对象调用函数方法时 , 系统会查看该对象真正类型是什么类型 , 然后去调用对应类型的方法 ; 对象是使用什么类型的构造函数创建的 , 其真正的类型就是这个类型 , 因此最终调用该类函数方法...函数使用要点 : 1. 构造方法 : 不能设置成函数, 如果将构造方法设置成函数 , 编译时会报错 ; 2...." << endl; } }; ③ 调用子类实现的纯函数 : //栈内存创建一个 Child 对象, 并调用其重写的父方法 Child child; //纯函数测试 parent

90820
领券