`
睡着的兔子
  • 浏览: 34938 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

构造函数不能为虚函数

阅读更多

构造函数不能声明为虚函数的原因:

    1,所谓虚函数就是多态情况下只执行一个,而从继承的概念来讲,总是先构造父类对象,然后才能使子类对象,如果构造函数设为虚函数,那么你在构造父类的构造函数时就不得不显式的调用构造,还有一个原因就是为了防错误的发生,试想如果你在子类中一不小心重写了个跟父类构造函数一样的函数,那么你的父类构造函数将被覆盖,也即不能完成父类的构造,就会出错。

class A
{
      public :
      virtual A()
      {
             cout<<"A"<<endl;
      }
            
};
class B: public A
{
      public:
      B()
      {
             cout<<"B"<<endl;
      }

     
};

在编译处,便已经提示无法通过,将virtual去掉

2,虚函数的主要意义在于被派生类继承从而产生多态,派生类的构造函数中,编译器会加入构造基类的代码,如果基类的构造函数用到了参数,则派生类在其构造函数中必须为基类给出参数,就是这个原因,原因有点绕,就是说如果派生类的构造函数必须跟父类一摸一样,这显然是不符合实际的

当然还有其他的解释:1,从存储空间角度,虚函数对应一个vtable,可是这个vtable其实是存储在对象的内存空间的。问题出来了,如果构造函数是虚的就需要通过vtable来调用,可是对象还没有实例化,也就是内存空间还,没有,无法找到vtable,所以构造函数不能为虚函数。

2,从使用角度 虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用。构造函数本身就是要初始化实例,那使用虚函数也就没有实例意义了,最开始的实例都没有初始化,何来多态呢。虚函数的作用于通过父类的指针或者引用来调用它的时候能够变成调用子类的那个成员函数。而构造函数实在创建对象的时候自动调用的,不可能通过父类的指针或引用去调用,因此规定构造函数不能为虚函数。

3,从实现上看,vtable在构造函数调用后才建立,因而构造函数不可能为虚函数,从实际含义上看,在调用构造函数时还不能确定对象的真实类型(子类要调用父类的构造函数),而且构造函数提供初始化,对象生命期只执行一次,不是对象的动态行为,也没有太大必要成为虚函数。

转载自http://blog.csdn.net/wangyadong/archive/2009/05/01/4138767.aspx   有轻微的修改

分享到:
评论

相关推荐

    构造函数不能为虚函数的理由

    构造函数不能为虚函数的理由 从存储空间角度,虚函数对应一个 vtable,这大家都知道,可是这个 vtable 其实是存储在对象的内存空间的。问题出来了,如果构造函数是虚的,就需要通过 vtable 来调用,可是对象还没有...

    构造函数不能声明为虚函数的原因及分析

    所以构造函数不能是虚函数。 2. 从使用角度,虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用。构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀。所以构造函数没有必要是虚函数。虚...

    构造函数不能声明为虚函数,析构函数可以声明为虚函数

    ### 构造函数不能声明为虚函数 构造函数在C++中主要用于初始化对象的状态,确保对象在使用前具有有效的初始值。构造函数不能声明为虚函数的原因主要涉及以下几个方面: 1. **对象类型未知**:当创建一个对象时,...

    为什么构造函数不能是虚函数

    ### 为什么构造函数不能是虚函数 #### 一、引言 在面向对象编程中,构造函数和虚函数是两个非常重要的概念。构造函数用于初始化对象的状态,而虚函数则支持多态性,允许基类指针或引用调用派生类的方法。这两种机制...

    派生类构造函数和析构函数的执行顺序

    但是,基类的构造函数和析构函数不能被继承。如果在派生类中需要对新增加的成员进行初始化,则需要加入派生类的构造函数。同样,派生类也需要添加析构函数来实现一些结束工作。 当创建对象时,编译系统会自动调用...

    构造函数Demo

    3. 构造函数不能是虚方法或抽象方法,也不能声明为static。 三、构造函数的应用场景 1. 初始化成员变量:通过构造函数,可以在对象创建时就对成员变量赋值,确保每个实例的初始状态。 2. 设置默认值:如果没有...

    C++构造函数,复制构造函数和析构函数专题[1].pdf

    总之,理解并熟练运用构造函数、复制构造函数、析构函数、继承、虚函数和多态性是掌握C++面向对象编程的关键。它们共同构成了C++强大而灵活的类层次结构和对象模型,为复杂软件设计提供了坚实的基础。通过深入研究和...

    一起学C#:构造函数和析构函数.rar

    2. **访问修饰符**:构造函数通常为`public`,以便在类的外部创建对象时调用。当然,也可以根据需求定义`private`、`internal`或`protected`的构造函数。 3. **无返回值**:构造函数不同于普通方法,它不能有任何...

    C++ 面试题精选

    但是如果我们要调用构造函数创建对象时,必须要知道对象的准确类型,因此构造函数不能为虚函数。 2. 不能被声明为虚函数的函数:普通函数(非成员函数)、构造函数、内联成员函数、静态成员函数、友元函数。普通...

    为何要虚析构函数.docx

    此外,虚函数对应的虚函数表是存放在对象的内存空间里,如果构造函数是虚函数,就需要通过虚函数表来调用,可是对象还没有实例化,也就是内存空间还没有,无法找到虚函数表,所以构造函数不能是虚函数。 虚析构函数...

    C++有子对象的派生类的构造函数

    1. 构造函数不应该是虚函数,因为它们在对象创建时调用,此时动态绑定(多态)还未生效。 2. 如果派生类没有定义自己的构造函数,编译器会自动生成一个默认构造函数,调用基类的默认构造函数。 总结,C++派生类的...

    c++ 构造函数中调用虚函数的实现方法

    4. `A`类构造函数执行完毕,`B`对象构造完成,类型确定为`B`。 5. 最后,通过指针`p`调用`test()`,由于`p`具有多态性,此时`func()`调用的是`B`类版本,输出`1`。 因此,构造函数中调用虚函数的行为取决于调用时刻...

    c#析构构造函数c#析构构造函数c#析构构造函数

    C#中的析构构造函数(Destructor)是一种特殊的方法,它在对象即将被垃圾回收器清除时执行,用于释放非托管资源。在C#中,析构函数以`~`符号开头,后面跟着类名,例如`~MyClass()`. 它们不同于常规的构造函数,构造...

    大华2021嵌入式(带答案)_嵌入式-常用知识&面试题库_大厂面试真题.docx

    1. 构造函数不能为虚函数:因为构造函数需要在对象创建时被调用,而虚函数表是在对象创建后才被创建的。 2. 父类的析构函数为什么是虚函数:为了在继承关系中正确释放资源,防止内存泄漏。 五、结构体对齐相关知识...

    虚函数与const指针

    构造函数不能是虚函数;析构函数可以是虚函数,而且通常声明为虚函数。 在使用虚函数时,还需要注意const指针的使用。const指针与指向const的指针是不同的。const指针是指针本身不能被修改,而指向const的指针是...

    C++构造函数

    C++构造函数,拷贝构造函数,虚函数,派生类

    C++ 虚继承对基类构造函数调用顺序的影响

    继承作为面向对象编程的一种基本特征,其使用频率...  假设derived 虚继承自base类,那么derivd与base是一种“has a”的关系,即derived类有一个指向base类的vptr。(貌似有些牵强!某些编译器确实如此)  因此虚

    C++面试题集锦.docx

    虚函数不能被声明为inline,因为内联函数的决定权在于编译器,而虚函数的动态绑定机制需要运行时确定。 17. **类成员初始化方式**: 通过成员初始化列表在构造函数中初始化成员,提高效率并确保正确初始化,特别是...

    完全掌握C++编程中构造函数使用的超级学习教程

    如果程序员没有定义构造函数,编译器会提供一个默认构造函数,该构造函数不接受任何参数。 2. 默认构造函数: 默认构造函数是编译器自动生成的,当类中没有定义任何构造函数时。如果需要禁止编译器生成默认构造...

Global site tag (gtag.js) - Google Analytics