虚函数-构造函数-析构函数

在C++里面,虚函数的作用就是  实现 多态

构造函数可以是  虚函数,但是这样做没有多大意义,特别是在有继承关系的时候估计就不行了,没有继承关系的时候,这个类就不会被创建,编译应该是没有问题的,

析构函数 在有继承的时候,经常用虚函数,因为在  子类有实例的时候,如果让父亲的指针指向  子类的实例,而子类的实例中有new了新的地址空间,那么调用父亲的析构函数,如果父亲的析构函数不是虚的,那么只负责把父亲自己的指针回收,但是子类中new就没有回收;而如果析构函数是虚函数,那么首先是释放子类申请的地址,然后再释放父亲自己的

构造函数里面能调用   虚函数吗?

答案:肯定是可以调用的,编译是不会有问题的。

那问题是在C++中输出是怎么样的呢?例如这个虚函数在父类中有一个简单的输出,在子类中也有一个输出,那么是先调用父类的输出,再调用子类的输出,因为这个时候C++规范中了,多态此时失效,

在12.7.3条中有明确的规定。这是一种特例,在这种情况下,即在构造子类时调用父类的构造函数,而父类的构造函数中又调用了虚成员函数,这个虚成员函数即使被子类重写,也不允许发生多态的行为。即,这时必须要调用父类的虚函数,而不子类重写后的虚函数。我想这样做的原因是因为在调用父类的构造函数时,对象中属于子类部分的成员变量是肯定还没有初始化的,因为子类构造函数中的代码还没有被执行。如果这时允许多态的行为,即通过父类的构造函数调用到了子类的虚函数,而这个虚函数要访问属于子类的数据成员时就有可能出错。

总之一句话是  静态绑定   不管是::还是this->这种操作符,都是静态绑定的,没有多态

如果是在java中,都是调用子类的构造函数,输出的结果是一样的,

析构函数能调用虚函数吗?

答案:是可以调用虚函数的,但是有一点,就是不能去调用纯虚函数  这个编译是通过的,但是运行时报错

继承类在构造的时候总是首先调用其基类的构造函数来对属于其基类的部分进行构造,在这个时候,整个类被当作基类来处理,继承类的部分对整个类来说好像不存在一样,直到基类的构造函数退出并进入继承类的构造函数,该类才被当作继承类来出来处理。对析构也一样,只是析构的顺序正好相反。

构造函数实现虚函数的效果:

从形状类Shape可以派生出圆Circle、三角形Triangle、矩形Rectangle、正方形Square等等。每个类都有一个成员函数Draw,表示在屏幕上画出自己的形状。使用者使用Shape*调用Draw,那么要使画出的形状都正确,必须根据对象类型来确定使用哪个Draw来画。将Draw在Shape中定义为虚函数,并在每个派生类中重新定义该函数,那么当程序运行时,系统自动调用合适的Draw函数版本。 构造函数不能为虚函数。原因是在建立一个对象时,构造函数必须知道其确切类型,否则编译器无法进行存贮空间的分配。 
要使构造函数具有虚函数的效果,通过以下方法: 
例: 
class Base { 
  public: 
    Base(); // 确省构造函数 
    Base(const Base&); // 拷贝构造函数 
    virtual Base* new_Obj() { return new Base();} // 具有虚构造函数效果 
    virtual Base* clone() { return new Base(*this);} // 具有虚构造函数效果 
    // …… 
};

class Derived : public Base { 
  public: 
    Derived (); // 确省构造函数 
    Derived (const Derived&); // 拷贝构造函数 
    // 对基类Base中的虚函数的重定义版本 
    virtual Derived * new_Obj() { return new Derived();} 
    virtual Derived * clone() { return new Derived(*this);} 
    // …… 
};

Base* create_Object(Base* ptr) 

  Base* p = ptr->new_Obj(); 
  return p; 
}

若ptr指向一个Base对象,则ptr->new_Obj()调用基类Base中的虚函数new_Obj建立一个动态的Base对象;若ptr指向一个Derived对象,则ptr->new_Obj()调用基类Derived中的虚函数new_Obj建立一个动态的Derived对象。

时间: 2024-12-12 08:05:25

虚函数-构造函数-析构函数的相关文章

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

构造函数不能声明为虚函数,析构函数可以声明为虚函数,而且有时是必须声明为虚函数.不建议在构造函数和析构函数里面调用虚函数. 构造函数不能声明为虚函数的原因是:1 构造一个对象的时候,必须知道对象的实际类型,而虚函数行为是在运行期间确定实际类型的.而在构造一个对象时,由于对象还未构造成功.编译器无法知道对象 的实际类型,是该类本身,还是该类的一个派生类,或是更深层次的派生类.无法确定... 2 虚函数的执行依赖于虚函数表.而虚函数表在构造函数中进行初始化工作,即初始化vptr,让他指向正确的虚函数

C++中为什么构造函数不能是虚函数,析构函数是虚函数

一, 什么是虚函数? 简单地说,那些被virtual关键字修饰的成员函数,就是虚函数.虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离:用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的策略. 所谓虚函数就是多态情况下只执行一个,而从继承的概念来讲,总是要先构造父类对象,然后才能是子类对象,如果构造函数设为虚函数,那么当你在构造父类的构造函数时就不得不显示的调用构造,还有一个原因就是为了防错,试想如果你在子类中一不小心重写了个跟

虚函数、纯虚函数、虚函数与析构函数

一.虚函数 只有用virtual声明类的成员函数,使之成为虚函数,不能将类外的普通函数声明为虚函数.因为虚函数的作用是允许在派生类中对基类的虚函数重新定义.所以虚函数只能用于类的继承层次结构中. 一个成员函数被声明为虚函数后,在同一类族中的类就不能再定义一个非virtual的但与该虚函数具有相同的参数(包括个数和类型)和函数返回值类型的同名函数. 根据什么考虑是否把一个成员函数声明为虚函数? ①  看成员函数所在的类是否会作为基类 ② 看成员函数在类的继承后有无可能被更改功能,如果希望更改其功能

深入学习c++(虚函数遇到析构函数就退化了)

1. 在构造函数和析构函数中调用的虚函数并不具备虚函数的特性 因为基类的构造函数先构造, 析构函数后析构 原文地址:https://www.cnblogs.com/douzujun/p/10792462.html

析构函数为什么不能声明为虚函数?析构函数为什么要声明为虚函数

多态中的虚函数表是在运行时创建的还是编译时创建的? 答:虚函数表在编译的时候就确定了,而类对象的虚函数指针vptr是在运行阶段确定的,这是实现多态的关键 (类的函数的调用并不是在编译时就确定的,而是在运行时才确定的,由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以声明为虚函数.虚函数和虚函数表是两个不同的东西,虚函数的调用是在运行时才确定的,虚函数表是在编译时就已经确定的了 .) 为什么构造函数不能声明为虚函数? 1.创建一个对象必须明确指出它的类型,否则无法创建,一个

C++构造函数和析构函数能否声明为虚函数?(转载)

构造函数为什么不能是虚函数 从存储空间角度,虚函数对应一个指向vtable虚函数表的指针,这大家都知道,可是这个指向vtable的指针其实是存储在对象的内存空间的.问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数. 从使用角度,虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用.构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀.所以构造函数没有必要是虚函数.虚函数的作用

构造函数为什么不能为虚函数 & 基类的析构函数为什么要为虚函数

一.构造函数为什么不能为虚函数 1. 从存储空间角度,虚函数对应一个指向vtable虚函数表的指针,这大家都知道,可是这个指向vtable的指针其实是存储在对象的内存空间的.问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数. 2. 从使用角度,虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用.构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀.所以构造函数没有必要是虚函

为什么构造函数不能为虚函数,而析构函数可以为虚函数

1.  构造函数为什么不能为虚函数? a.  存储空间角度: 虚函数的调用需要虚函数表指针,而该指针存放在对象的内容空间中,需要调用构造函数才可以创建他的值,否则即使开辟了空间,则虚表指针为随机值,不会找到构造函数:若构造函数声明为虚函数,那么由于对象还未创建,还没有内存空间,更没有虚函数表地址用来调用虚函数——构造函数了. b.  使用上:  从实现上看,vbtl在构造函数调用后才建立,因而构造函数不可能成为虚函数: 虚函数主要是实现多态,在运行时才可以明确调用对象,根据传入的对象类型,来调用

31.C++-虚函数之构造函数与析构函数分析

1.构造函数不能为虚函数 当我们将构造函数定义为虚函数时,会直接报错: 首先回忆下以前学的virtual虚函数概念: 如果类定义了虚函数,创建对象时,则会分配内存空间,并且为该父类以及其所有子类的内存空间上额外分配一个虚函数表. 虚函数表的作用在于,存储每个类的相同的虚函数名,然后每一次虚函数调用,都会去虚函数表查找地址 分析: 假如构造函数是虚函数的话,由于对象开始还未分配内存空间,所以根本就无法找到虚函数表,从而构造函数也无法被调用.所以构造函数是不能成为虚函数. 2. 析构函数可以为虚函数