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

1.构造函数不能为虚函数

当我们将构造函数定义为虚函数时,会直接报错:

首先回忆下以前学的virtual虚函数概念:

  • 如果类定义了虚函数,创建对象时,则会分配内存空间,并且为该父类以及其所有子类的内存空间上额外分配一个虚函数表.
  • 虚函数表的作用在于,存储每个类的相同的虚函数名,然后每一次虚函数调用,都会去虚函数表查找地址

分析:

假如构造函数是虚函数的话,由于对象开始还未分配内存空间,所以根本就无法找到虚函数表,从而构造函数也无法被调用.所以构造函数是不能成为虚函数.

2. 析构函数可以为虚函数

首先回忆下析构函数:

当某个内对象被注销时,编译器会自动顺序调用该类以及其父类的析构函数,而不会调用派生类的析构函数.

虚析构函数的好处

假如我们通过派生类生成基类对象时,如果析构函数是虚函数,则我们释放其基类对象时,能使整个类(包括派生类)对象完全释放,如果析构函数只是普通函数,则不能析构完全.

分析:

所以当我们在用多态的时候(通过基类来调用派生类成员函数),析构函数最好为虚函数

示例如下:

#include <iostream>
using namespace std;

class ClassBase
{
public:
  ClassBase(){};
  virtual ~ClassBase()
  {
     cout<<"~ClassBase()"<<endl;
  }

  virtual void func()                         //虚函数成员
  {
      cout<<"ClassBase: func()"<<endl;
  }
};

class ClassDerived : public ClassBase
{
public:
  ClassDerived(){};
  ~ClassDerived()
  {
      cout<<"~ClassDerived()"<<endl;
  }
  void func()                    //虚函数成员
  {
      cout<<"ClassDerived: func()"<<endl;
  }
};

 int main()
{
   ClassBase *p = new  ClassDerived;

   p->func();                   //通过多态来调用派生类虚函数

   delete p;

   return 0;
}

打印如下:

原文地址:https://www.cnblogs.com/lifexy/p/10629539.html

时间: 2024-09-28 01:41:40

31.C++-虚函数之构造函数与析构函数分析的相关文章

虚函数与构造函数、析构函数

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

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

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

[转载]虚函数在构造函数中,已经失去了虚函数的动态绑定特性

class A { public: A() { Print(); } virtual void Print() { printf("A is constructed.\n"); } }; class B: public A { public: B() { Print(); } virtual void Print() { printf("B is constructed.\n"); } }; int _tmain(int argc, _TCHAR* argv[])

关于C#虚函数和构造函数的一点理解

虚函数感觉总是很神秘,在本质的原理上一直也没有弄得很透彻,今天又有一点的新的感悟,纪录下来,有时间的话可以去研究一下C++对象模型 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace CSGrammar 8 { 9 class Program 10 { 11 static

C++内敛函数,构造函数,析构函数,浅拷贝

inline //inline函数可以有声明和实现,但是必须在同一文件//inline函数不能分成头文件和实现文件 inline int add(int x, int y){ //一般不要放循环语句 return x + y;} //如果是自定义类类型,都要大写首字母class Computer{public://public成员可以在类之外访问 //public成员称为类对外的接口.功能.服务 //对成员函数采用驼峰方式进行命名 void setBrand(const char * brand

你好,C++(37)上车的人请买票!6.3.3 用虚函数实现多态

6.3.3  用虚函数实现多态 在理解了面向对象的继承机制之后,我们知道了在大多数情况下派生类是基类的“一种”,就像“学生”是“人”类中的一种一样.既然“学生”是“人”的一种,那么在使用“人”这个概念的时候,这个“人”可以指的是“学生”,而“学生”也可以应用在“人”的场合.比如可以问“教室里有多少人”,实际上问的是“教室里有多少学生”.这种用基类指代派生类的关系反映到C++中,就是基类指针可以指向派生类的对象,而派生类的对象也可以当成基类对象使用.这样的解释对大家来说是不是很抽象呢?没关系,可以

继承中的虚函数、纯虚函数、普通函数

一.虚函数 被virtual关键字修饰的类成员函数就是虚函数.虚函数的作用就是实现运行时的多态性,将接口与实现分离.简单理解就是相同函数有着不同的实现,但因个体差异而采用不同的策略. 基类中提供虚函数的实现,为派生类提供默认的函数实现.派生类可以重写基类的虚函数以实现派生类的特殊化.如下: class Base{ public: virtual void foo() { cout<<"Base::foo() is called"<<endl; } }; clas

C++程序设计POJ》《WEEK6 多态与虚函数》

问题: 虚函数都是同名 同参数表的吗? 虚函数和普通成员函数的区别 虚函数可以多态,其他不行 在构造函数和析构函数中调用 虚函数 不是多态 派生类还没有初始化好 MyCompare() qsort 怎么表示排序关系 虚函数表地址!! 虚函数?在类的定义中,前面有 virtual 关键字的成员函数就是虚函数.class base{ virtual   int get() }; int base::get(){ } virtual 关键字只用在类定义里的函数声明中,写函数体时不用.多态的表现形式一

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

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