精华内容
下载资源
问答
  • 定义派生类时构造函数及析构函数调用顺序
    2019-03-10 12:22:37

    1.调用基类的构造函数,对基类数据成员初始化;
    2.调用内嵌对象成员的构造函数,对内嵌数据成员初始化;
    3.执行派生类的构造函数体,对派生类数据成员初始化;
    4.调用析构函数的顺序正好与调用构造函数的顺序相反,先执行派生类的析构函数,再执行内嵌对象成员,最后执行基类的析构函数。
    如下代码:

    #include <iostream>
    using namespace std;
    class Base{          //声明基类 
     public:
      Base(int i)   //基类的构造函数 
      {
       x = i;
       cout<<"Constructing base class\n";
      }
      ~Base()  //基类的析构函数 
      {
       cout<<"Destructing base class\n";
      }
      void show()
      {
       cout<<"x="<<x<<endl;
      }
      private:
       int x;
    }; 
    class Derived:public Base      //声明公有派生类 Derived
    {
     public:
      Derived(int i):Base(i),d(i)   //派生类的构造函数 
      {
       cout<<"Constructing derived class\n";
      }
      ~Derived()           //派生类的析构函数 
      {
       cout<<"Destructing dereived class\n";
      }
      private:
       Base d;     //d为基类对象,作为派生类的内嵌对象成员 
    };
    int main()
    {
     Derived obj(5);
     obj.show();
     return 0;
    }
    

    结果如下
    在这里插入图片描述

    更多相关内容
  • 原因:基类对象的指针操作派生类对象时,防止析构函数只调用基类的,而不调用派生类的 下面详细说明: //基类 class A{ public : A(){ cout<<"A构造函数"<<endl; } ~A(){cout<<"A被...

    原因:基类对象的指针操作派生类对象时,防止析构函数只调用基类的,而不调用派生类的

     

    下面详细说明:

     

    //基类
     
    class A{
       public :
           A(){ cout<<"A构造函数"<<endl; }
           ~A(){cout<<"A被销毁了"<<endl;}
           void Do(){
               cout<<"A要做点什么"<<endl;
           }
    };
    //派生类
     
    class B :public A{
        public :
            B(){ cout<<"B构造函数"<<endl;}
            ~B(){ cout<<"B被销毁了"<<endl;}
            void Do(){ cout<<"B要做点什么"<<endl;}
    };

     

    (1)派生类 指针=new 派生类;

             B      *p   =new B;      那么就会执行基类构造函数,派生类构造函数

             p->Do();   通过派生类指针可以调用派生类的成员函数

             delete p;     先调用派生类析构函数,在调用基类构造函数

             

     派生类指针操作派生类成员函数

     

    (2)派生类 指针=new 基类;  会出错,基类指针不能转换成派生类指针

     

    (3)基类 指针 = new 派生类;  (派生类指针转化成基类指针)

           A    *p    = new B;     依旧要先调用基类构造函数,再派生类构造函数

           p ->Do();    通过基类指针调用基类成员函数,此处只能调用基类里面有的成员函数,当调用派生类中成员函数会提示基类中并没有这个成员

           delete p;      这里只会调用基类的析构函数,所以内存释放并不完全

     派生类指针转换成基类指针

     

       

    (4)上面(3)知道了这样影响了内存的释放完整程度,所以我们通过引入虚函数机制,将基类的析构函数定义成虚函数

     

    //基类
     
    class A{
       public :
           A(){ cout<<"A构造函数"<<endl; }
           virtual ~A(){cout<<"A被销毁了"<<endl;}
           void Do(){
               cout<<"A要做点什么"<<endl;
           }
    };
    //派生类
     
    class B :public A{
        public :
            B(){ cout<<"B构造函数"<<endl;}
            ~B(){ cout<<"B被销毁了"<<endl;}
            void Do(){ cout<<"B要做点什么"<<endl;}
    };

     

    然后 delete p;就会释放派生类,释放基类

     析构函数变成了虚函数,发现可以正常释放内存

     

     

    总结:引入虚函数后,因为基类对象的指针可以指向派生类的对象(多态性),所以如果删除指针delete p,那么就会调用派生类得析构函数,但是派生类的析构函数就会调用基类的析构函数,这样整个派生类的对象完全被释放。但是如果不被声明成虚函数,那么删除指针时,只会调用基类的析构函数,而不会调用派生类的析构函数,这样释放对象就只释放不完全,所以把析构函数定义成虚函数是十分必要的。

     

    还有派生类指针转换成基类指针的时候,调用同名成员函数的时候,一定要调用基类的成员函数,因为此时基类的成员函数覆盖了派生类的同名成员函数。这时也需要引入虚函数来实现多态,就可以调用派生类的成员函数了

    展开全文
  • 派生类的构造函数和析构函数的...而撤销对象时,先执行派生类的析构函数,执行基类的构造函数。 #include<iostream> using namespace std; class A{ public: A() { cout<<"1"<<'\n'; ...

    派生类的构造函数和析构函数的执行顺序:
    一般情况下,创建派生类的对象时,首先是执行基类的构造函数,随后执行派生类的构造函数。而在撤销对象时,先执行派生类的析构函数,在执行基类的构造函数。

    #include<iostream>
    using namespace std;
    class A{
    	public:
    		A()
    		{
    		cout<<"1"<<'\n';
    		}
    		~A()
    		{
    		cout<<"4"<<'\n';
    		}
    	};
    class B:public A{
    		public:
    			B()
    			{
    				cout<<"2"<<'\n';
    			}
    			~B()
    			{
    				cout<<"3"<<'\n';
    			}
    };
    int main()
    {
    B b;
    return 0;
    };
    

    运行结果:
    在这里插入图片描述
    此结果清楚的显示了派生类的构造和析构与基类的运行顺序。

    展开全文
  • 基类指针指向派生类对象,只能调用基类原有的,而不能调用派生类中的 从pa=&b,这里可看出,解释一下:这里取得是b的首地址,而pa的长度是由数据类型的内存所占大小决定的 pb=&a 的话是会报错的,因为pb的...

    在这里插入图片描述
    A作为基类,B作为派生类
    基类指针指向派生类对象,只能调用基类原有的,而不能调用派生类中的
    从pa=&b,这里可看出,解释一下:这里取得是b的首地址,而pa的长度是由数据类型的内存所占大小决定的
    pb=&a 的话是会报错的,因为pb的长度已经超出了A的内存范围,多出的那一部分可能会乱指,导致安全性缺失
    当然pb->showA()也是会报错的,同样的道理。
    所以,派生类指针不能指向基类对象

    构造函数能定义为虚函数?
    不能,虚函数是需要通过对应的vtable虚指针来调用,而虚指针是在对象创建完毕才有的,但是构造函数是要在对象创建时调用,这之间无法同时达到要求,所以构造函数不能定义为虚函数。

    用基类的指针去指向对象,在析构时就会出现问题,因为派生类对象在析构时是先释放派生类,再释放基类(正确的做法),而用基类指针指向派生类对象,析构时是只析构基类(错误的做法),从而导致派生类的那一部分没有被释放掉,成为僵尸内存或称内存泄漏
    所以用基类指针指向派生类对象,要用virtual析构函数,使基类指针可以指向派生类中(virtual的作用:根据对象的实际类型,调用相应的类型函数。),使得再手动释放内存delete 时,可以调用派生类的析构函数,从而自动调用基类的析构函数。

    展开全文
  • 派生类构造函数和析构函数的执行顺序 链接: link. #include <iostream> using namespace std; class Contained1 { public: Contained1() { cout << "Contained1 ctor\n"; }//构造constructor ~...
  • C++派生类中如何初始化基类对象

    千次阅读 2018-08-26 16:41:42
    今天收到盛大的面试,问我一个问题,关于派生类中如何初始化基类对象,我派生类对于构造函数不都是先构造基类对象,然后构造子类对象,但是如果我们成员初始化列表先初始化派生类的私有成员,函数内去调用...
  • 一、派生类对象中基类构造函数和派生类中构造函数调用顺序(WIN7 64位 VS2012) (1)、先执行派生类的构造函数还是先执行基类中的构造函数? 利用下面这段代码进行打印测试 #include using namespace std; // 基类 ...
  • 2、本质:不是重载声明而是覆盖 3、调用方式:通过基类指针或引用,执行会根据指针所指的对象的类,决定调用哪个函数 虚析构函数的作用: 1、可能通过基类指针删除派生类对象 2、如果你打算允许他人通过基类指针...
  •  牛客网原题,记录下来...· 创建派生类对象时,构造函数的执行顺序是:基类的构造函数→派生类的构造函数; · 撤消派生类对象时,析构函数的执行顺序是:派生类的构造函数→基类的构造函数。 当派生类中含
  • C++由于基类指针可以指向不同的派生类对象,因此当赋予基类指针不同的地址,要注意之前的派生类对象的内存释放。int main(){ Parent* ptr = new Child1; Child2 myChild2; Child3 myChild3; ptr->show(); ...
  • C++派生类

    千次阅读 2022-02-09 10:35:43
    学习笔记:C++派生类
  • ◆由于构造函数不能被继承,因此,派生类的构造函数中除了对派生类中数据成员进行初始化外,还必须通过调用直接基类的构造函数来对基类中数据成员初 始化,一般地将,对派生类中数据成员初始化放在该派生类构造函数...
  • 当创建派生类对象时: 基类的构造函数——>派生类的构造函数; 当撤消派生类对象时: 派生类的析构函数——>基类的析构函数。 1.派生类的构造函数和析构函数的调用顺序 (1) 输出的是:基类的构造...
  • 派生类的构造函数与析构函数的调用顺序 前面已经提到,构造函数和析构函数的调用顺序是先构造的后析构,后构造的先析构。 那么基类和派生类中的构造函数和析构函数的调用顺序是否也是如此呢...2 )成员类对象构造...
  • 通常情况下,当创建派生类对象时,首先执行基类的构造函数,随后再执行派生类的构 造函数;当撤销派生类对象时,则先执行派生类的析构函数,随后再执行基类的析构函数。 下列程序的运行结果,反映了派生类的构造...
  • C++ 派生类的析构函数的调用顺序为:A) 基类、派生类对象成员类的析构函数  B) 派生类对象成员类和基类的析构函数  C) 对象成员类、派生类和基类的析构函数  D) 派生类、基类和对象成员类的析构函数 答案是...
  • 派生类对象从内存中撤销一般先调用派生类的析构函数,然后再调用基类的析构函数。1、系统会只执行基类的析构函数,而不执行派生类的析构函数。如下例子 [例12.3] 基类中有非虚析构函数的执行情况。为简化...
  • 讲派生类的构造和析构函数时候我们先介绍类的兼容性。 类的兼容性: 类的兼容性是指需要基类对象的任何地方都可以使用派生类...替代之后,派生类对象可以作为基类对象使用,但只能使用从基类继承的成员。 派生类
  • C++中对象,封装,继承(派生),多态

    千次阅读 多人点赞 2021-02-16 12:45:44
    就是同一事物的总称,比如我(一个对象)可以讲话,那么基本上所有人都具备这个属性,就将我这一对象称为的思想就是这样产生的。更恰当的描述:就是世间事物的...C++语言中,对象的行为是以函
  • 派生类的构造函数

    千次阅读 多人点赞 2017-06-07 18:55:36
    因此执行派生类的构造函数,应该调用基类的构造函数。具体的形式如下: 派生类构造函数名(总形式参数表列):基类构造函数名(实际参数表列){派生类中新增数据成员初始化语句} 举个例子: Student1(int n,...
  • 1,如果以一个基础类指针指向一个衍生类对象(派生类对象),那么经由该指针只能访问基础类定义的函数(“实函数”暂且这么叫)( 静态联翩 ) 2,如果以一个衍生类指针指向一个基础类对象,必须先做强制...
  • 必须是QObject的派生类 2.必须指定了parent对象 即:Qt 中 父亲被删除的时候会自动销毁他的孩子。所以如果New出来的并且没有父亲。那么则需要手动删除它。需要,不然那块空间就一直占用了QLabel* lb=new QLabel();...
  • 派生类的构造函数 、派生类的析构函数 、函数的重载、隐藏与覆盖
  • C#中释放COM对象

    千次阅读 2018-11-07 17:36:21
    公共语言运行(Common Language Runtime,CLR)通过...每个RCW为它所封包的COM对象创建并维持一个接口指针缓存,并且直到RCW不再需要使用释放对COM对象的引用。此时,运行将对RCW执行垃圾回收(Garbage...
  • 前言:设计派生类的构造函数,希望执行派生类的构造函数,使派生类的数据成员和基类的数据成员同时被初始化。解决这个问题的思路是:执行派生类的构造函数,调用基类的构造函数。5.1简单的派生类的构造...
  • 1. 指向基类的指针可以指向派生类对象,当基类指针指向派生类对象时,这种指针只能访问派生对象从基类继承而来的那些成员,不能访问子类特有的元素,除非应用强类型转换,例如有基类B和从B派生的子类D,则B *p;...
  • 目录 面向对象编程 常用术语/名词解释 ...初始化:通过调用类对象来创建实例 __init__()“构造器”方法 __new__()“构造器”方法 __del__()“解构器”方法 实例属性 构造器中首先设置实例属性 默认参

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 71,580
精华内容 28,632
关键字:

在释放派生类的对象时