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

从基类构造函数调用派生类的虚函数?

从基类构造函数调用派生类的虚函数是一个复杂的问题,涉及到C++编程语言的多态性和构造函数的执行顺序。在C++中,构造函数的执行顺序是从基类到派生类,而虚函数的调用是在运行时根据对象的实际类型来决定的。因此,如果在基类的构造函数中调用了派生类的虚函数,则会导致未定义的行为。

为了避免这种情况,可以采用以下方法:

  1. 将虚函数的调用移到构造函数之外,在构造函数执行完毕后再调用虚函数。
  2. 将虚函数的调用放在基类的构造函数中,但是需要确保虚函数的实现在基类的构造函数之后定义。
  3. 使用工厂模式或其他设计模式来避免在构造函数中调用虚函数。

以下是一个示例代码,展示了如何在基类的构造函数中调用派生类的虚函数:

代码语言:c++
复制
class Base {
public:
    Base() {
        func();
    }
    virtual void func() {
        cout << "Base::func()"<< endl;
    }
};

class Derived : public Base {
public:
    Derived() {
        func();
    }
    void func() override {
        cout << "Derived::func()"<< endl;
    }
};

int main() {
    Derived d;
    return 0;
}

在这个示例中,基类的构造函数会调用派生类的虚函数,导致输出结果不符合预期。为了避免这种情况,可以采用上述方法之一来重新设计代码。

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

相关·内容

派生类多态函数

通常在层次关系根部有一个,其他则直接或间接继承而来,这些继承得到称为派生类负责定义在层次关系中所有共同拥有的成员,而每个派生类定义各自特有的成员。...成员函数与继承派生类可以继承其成员, 然而有时候派生类必须对其重新定义。派生类需要对这些操作提供自己新定义以覆盖继承而来旧定义。...根据引用或指针所绑定对象类型不同,该调用可能执行版本,也可能执行某个派生类版木,通过在其成员函数声明语句之前加上关键字virtual使得该函数执行动态绑定。...任何构造函数之外非静态函数都可以是函数。 关键字virtual只能出现在内部声明语句之前而不能用于外部函数定义。 如果把一个函数声明成函数,则该函数派生类中也是函数。...成员函数如果没被声明为函数,则其解析过程发生在编译时而非运行时。就会按照实际情况调用派生类可以继承定义在成员,但是派生类成员函数不一定有权访问继承而来成员。

15120

c++继承 派生类 函数

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

1K20

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

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

7210

禁止在构造函数调用函数

构造函数调用函数会导致程序出现莫名其妙行为,这主要是对象还没有完全构造完成。...这是因为构造函数调用一个定义在本类中但是为派生类所重写函数,程序运行时候会调用派生类版本,程序在运行期类型是 A 而不是 B。...派生类对象所具备成员变量默认值是由初始化语句或者系统来确定,因此开发人员如果想要在构造函数中给这些变量赋值那么就必须等到程序运行到构造函数时才可以。...Tip:C# 对象运行期类型是一开始就定好,即便是抽象也依然可以调用其中方法。 小结 在构造函数调用函数会导致代码严重依赖于派生类实现,然后这些实现是无法控制且容易出错。...也就是说在这种情况下派生类必须定义默认构造函数,并且不能定义别的构造函数,这将会给开发人员带来很大负担。

1.6K20

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

,一个对象需要调用构造函数完成实例化,这里形成了一个悖论 在意义上,将构造函数声明为函数没有意义,函数主要是实现多态,c++多态是在运行时构建调用不同函数,而不是根据情况动态调用构造函数...构造函数是不行,但是析构函数作为函数确实常用,特别是析构函数一定要声明为函数。首先既然对象存在,那么函数表肯定存在,所以析构函数作为函数是合理。...这时候如果是指针指向子类对象,那么删除指针,只会调用析构函数,因为这时候对象类型是对象,析构函数没有动态绑定,只会调用当前对象类型析构。...但是如果将析构函数声明为函数,则能成功调用子类析构函数 #include using namespace std; class Father { public:...//Father f 代码运行后,构造函数调用了父函数,我们本来想要调用子类函数

1.2K50

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

虽然可以对函数进行实调用,但程序员编写函数本意应该是实现动态联编。在构造函数调用函数函数入口地址是在编译时静态确定,并未实现调用。...当创建某个派生类对象时,如果在它构造函数调用函数,那么此时派生类构造函数并未执行,所调用函数可能操作还没有被初始化成员,将导致灾难发生。...所以,一个构造函数在执行时,并不能保证该函数所能访问到指针就是当前被构造对象最后所拥有的指针,因为后面派生类构造函数会对当前被构造对象指针进行重写,因此无法完成动态联编。...输出结果来看,A析构函数对show()调用并没有发生调用。...概念上说,析构函数是用来销毁一个对象,在销毁一个对象时,先调用该对象所属析构函数,然后再调用析构函数,所以,在调用析构函数时,派生类对象“善后”工作已经完成了,这个时候再调用派生类中定义函数版本已经没有意义了

91910

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

虽然可以对函数进行实调用,但程序员编写函数本意应该是实现动态联编。在构造函数调用函数函数入口地址是在编译时静态确定,并未实现调用。...当创建某个派生类对象时,如果在它构造函数调用函数,那么此时派生类构造函数并未执行,所调用函数可能操作还没有被初始化成员,浙江导致灾难发生。...所以,一个构造函数在执行时,并不能保证该函数所能访问到指针就是当前被构造对象最后所拥有的指针,因为后面派生类构造函数会对当前被构造对象指针进行重写,因此无法完成动态联编。...输出结果来看,A析构函数对show()调用并没有发生调用。...概念上说,析构函数是用来销毁一个对象,在销毁一个对象时,先调用该对象所属析构函数,然后再调用析构函数,所以,在调用析构函数时,派生类对象“善后”工作已经完成了,这个时候再调用派生类中定义函数版本已经没有意义了

2.8K30

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

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

1.5K00

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

谜题 在C#中,用virtual关键字修饰方法(属性、事件)称为方法(属性、事件),表示该方法可以由派生类重写(override)。...我们在构造函数调用方法,碍着ReSharper什么事儿了? 其实这个警告就是提醒我们不要在非封闭类型构造函数调用方法或属性。但为什么这样做不合适呢?在解惑之前,我们先来了解两个概念。...你也许已经猜到了,它结果是: Base constructor Derived constructor 我们在初始化一个对象时,总是会先执行构造函数,然后再执行子类构造函数。...Virtual member call in constructor警告是因为,对于Base b = new Derived();这样代码: 构造函数执行要早于子类构造函数 构造函数中对于方法调用...而有些时候,为了业务需要,我们不得不在实体构造函数中对这些属性进行某些操作(比如初始化)。 我认为这么做是技术选型所致必然结果,是完全可以接受

1.2K110

python 子类调用构造函数实例

当子类继承父后,需要调用方法和属性时,需要调用初始化函数。...,但新构造函数没有初始化父,当没有初始化父构造函数时,就会报错。...super函数返回一个super对象,解析过程自动查找所有的父和父,当前和对象可以作为super函数参数使用,调用函数返回方法是超方法。...使用super函数如果子类继承多个父只许一次继承,使用一次super函数即可。 如果没有重写子类构造函数,是可以直接使用父属性和方法。...以上这篇python 子类调用构造函数实例就是小编分享给大家全部内容了,希望能给大家一个参考。

3.5K30

怎么用super调用构造函数

Box派生并没有体现出它们实际上是多么有效和强大。例如,BoxWeight构造函数明确初始化了Box( )width、height和depth成员。...使用super调用构造函数 子类可以调用中定义构造函数方法,用super下面形式:java复制代码super(parameter-list); 这里,parameter-list定义了超构造函数所用到所有参数...既然构造函数可以被重载,可以用超定义任何形式调用super( ),执行构造函数将是与所传参数相匹配那一个。...这仍然调用构造函数Box(Box ob)。前面已经提醒过,一个超变量可以引用作为任何一个它派生对象。因此,我们可以传递一个BoxWeight对象给Box构造函数。...当然,Box只知道它自己成员信息。让我们复习super( )中关键概念。当一个子类调用super( ),它调用直接超构造函数。这样,super( )总是引用调用直接

9910

小朋友学C++(10):子类构造函数调用构造函数

哲学层面来看,子类会继承父除private以外所有成员。 因为构造函数是公有的,所以理所当然地会被子类继承。...分析: 这里构造函数写法是 Rectangle() : Shape() { 子类构造函数本身语句; } 这是先调用构造函数,再执行它本身语句。运行结果也可以看出这一点。...那么,如果不显示调用构造函数Shape()呢?父构造函数就不被调用了吗? 咱们可以用下面的程序来验证。...分析: 运行结果可以看出,程序1和程序2运行结果完全一致。也就是说,Shape()即使不显示调用,实际上也会被调用。并且调用顺序优先于子类本身构造函数

1.3K60

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

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

67910

java构造函数调用另一个构造函数_java中构造函数

参考链接: Java程序另一个调用一个构造函数 package demo03; /*  * 构造方法是专门用来创建对象方法,当我们通过关键字new来创建对象时,其实就是在调用构造方法  * 格式:... * public 名称(参数类型 参数名称){  *         方法体  *   * }  * 注意事项:  * 1.构造方法名称必须和所在名称完全一样,就连大小写也要一样  * 2.构造方法不要写返回值类型...,连void都不写  * 3.构造方法不能return一个具体返回值  * 4.如果没有编写任何构造方法,那么编译器将会默认赠送一个构造方法,没有参数,方法体什么都不做  * 5.一旦编写了至少一个构造方法...,那么编译器将不再赠送  * 6.构造方法也是可以进行重载。  ...;     }     //有参数构造方法     public Student(String name,int age) {         System.out.println("全参构造方法执行啦

4.4K60

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

到目前为止,被调用函数应该只属于构造对象本身,而不是可能存在于派生类某个覆盖函数。那样做非常难理解。...最坏情况,在构造函数或者析构函数中直接或间接调用一个没有实现函数会导致没有定义行为。...参考工厂函数以便了解如何达成调用派生类功能效果而不必承担引起未定义行为风险。...构造函数和析构函数调用函数并不是本身有什么错误。这种调用语义是安全。然而,经验表明这样调用很少是必须,很容易扰乱维护者,如果被新手使用会成为错误源。...提示来自构造函数或析构函数函数调用

74950

构造函数和析构函数

一、构造函数和析构函数由来 数据成员不能在声明时候初始化,为了解决这个问题? 使用构造函数处理对对象初始化。...二、构造函数 (1)初识初始化 C++支持两种初始化形式:复制初始化和直接初始化,对于直接初始化直接调用实参匹配构造函数,复制初始化总是调用复制构造函数。...“当用于类型对象时,初始化复制形式和直接形式有所不同:直接初始化直接调用与实参匹配构造函数,复制初始化总是调用复制构造函数。...四、总结 1、复制初始化无优化调用方式,复制初始化首先使用指定构造函数创建一个临时对象,然后用复制构造函数将那个临时对象复制到正在创建对象。...2、对于复制初始化构造函数调用方式,编译器已经将其作为普遍方法而不是作为一种优化。 3、初始化过程中“=”,是隐式调用复制构造函数,而不是调用赋值运算符函数

1.8K20
领券