派生类的构造函数和析构函数

article/2025/10/2 4:52:07

派生类的构造和析构函数

派生类的构造函数

在定义派生类时,派生类并没有把基类的构造函数和析构函数继承下来。因此,对继承的基类成员初始化的工作要由派生类的构造函数承担,同时基类的析构函数也要被派生类的析构函数来调用

1.派生类构造函数的定义

在执行派生类的构造函数时,使派生类的数据成员和基类的数据成员同时都被初始化。其定义形式如下:

派生类名(形式参数列表):基类名(基类构造函数实参列表),派生类初始化列表
{派生类初始化函数体
}

“基类名(基类构造函数实参列表)”即是调用基类构造函数,而派生类新增的数据成员可以在“派生类初始化列表”初始化,也可以在“派生类初始化函数体”中初始化

派生类构造函数的调用顺序是:
(1)调用基类构造函数;(2)执行派生类初始化列表;(3)执行派生类初始化函数体;

例:

class Point { int x,y;public:Point(int a,int b):x(a),y(b) { } //构造函数
};
class Rect: public Point {int h,w;public:Rect(int a,int b,int c,int d): Point(a,b),h(c),w(d) { } //派生类构造函数
};

2.组合关系的派生类构造函数

假定派生类A和类B的关系是组合关系,类A中有类B的子对象。如果类B有默认构造函数,或者参数全是默认参数的构造函数,或者有无参数的构造函数,那么类A的构造函数中可以不用显式初始化子对象。编译器总是会自动调用B的构造函数进行初始化

可以在一个类的构造函数中显式地初始化其子对象,初始化式只能在构造函数初始化列表中,形式为:

类名(形式参数列表): 子对象名(子对象构造函数实参列表),类初始化列表
{类初始化函数体
}

调用顺序为:
(1)调用基类构造函数;(2)调用子对象构造函数,各个子对象时按其声明的次序先后调用;(3)执行派生类初始化列表;(4)执行派生类初始化函数体;

说明:
(1)如果在基类和子对象所属类的定义中都没有定义带参数的构造函数,而且也不需要对派生类自己的数据成员初始化,那么可以不必显式地定义派生类构造函数。派生类会合成一个默认构造函数,并在调用派生类构造函数时,会自动先调用基类的默认构造函数和子对象所属类的默认构造函数

例:

class A { }; //合成默认构造函数
class B { }; //合成默认构造函数
class D: public B { A a; }; //派生类合成默认构造函数

(2)如果在基类中没有定义构造函数,或定义了没有参数的构造函数,那么,在定义派生类构造函数时,可以不显式地调用基类构造函数。在调用派生类构造函数时,系统会自动先调用基类的无参数构造函数或默认构造函数

例:

class B { public: B() { } }; //无参数构造函数
class D: public B {D() { } //派生类构造函数不必显式调用基类构造函数
};

(3)如果在基类或子对象所属类的定义中定义了带参数的构造函数,那么就必须显式地定义派生类构造函数,并在派生类构造函数中显式地调用基类或子对象所属类的构造函数

例:

class A { public: A(int) { } }; //有参数构造函数
class B { public: B(int) { } }; //有参数构造函数
class D: public B {D(int x): a(x),B(x) { } //显式调用基类或子对象构造函数A a;
};

(4)如果在基类中既定义了无参数的构造函数,又定义了有参的构造函数(构造函数重载),则在定义派生类构造函数时,既可以显式调用基类构造函数,也可以不调用基类构造函数

在调用派生类构造函数时,根据构造函数的内容决定调用基类的有参数的构造函数还是无参数的构造函数

可以根据派生类的需要决定采用哪一种方式

派生类的析构函数

在派生时,派生类是不能继承基类的析构函数的,也需要通过派生类的析构函数去调用基类的析构函数

派生类中可以根据需要定义自己的析构函数,用来对派生类中所增加的成员进行清理工作。基类的清理工作仍然由基类的析构函数负责

在执行派生类的析构函数时,系统会自动调用基类的析构函数和子对象的析构函数,对基类和子对象进行清理

析构函数调用的顺序与构造函数正好相反:先执行派生类自己的析构函数,对派生类新增加的成员进行清理,然后调用子对象的析构函数,对子对象进行清理,最后调用基类的析构函数,对基类进行清理

例:

#include<iostream>
using namespace std;class A {public:A() {cout<<"A constructor"<<endl;}~A() {cout<<"A destructor"<<endl;}
};class B: public A {public:B() {cout<<"B constructor"<<endl;}~B() {cout<<"B destructor"<<endl;}
};class C: public B {public:C() {cout<<"C constructor"<<endl;}~C() {cout<<"C destructor"<<endl;}
};int main()
{C text;return 0;
}

运行结果:
在这里插入图片描述


http://chatgpt.dhexx.cn/article/eEh5BqJP.shtml

相关文章

C++构造函数和析构函数总结

构造函数&#xff1a; <1>作用&#xff1a;赋初值,初始化对象的数据成员,由编译器帮我们调用。 <2>特点&#xff1a;①函数名和类名一样。②没有返回值。③支持有参/无参。④可以重载。 <3>调用时机&#xff1a;在类的对象创建时刻,编译器帮我们调用构造函数…

C++基础:构造函数与析构函数

数据成员多为私有的&#xff0c;要对他们进行初始化&#xff0c;必须用一个公有函数来进行。同时这个函数应该在定义对象时自动执行一次。称为构造函数。 构造函数的用途&#xff1a;1&#xff09;创建对象&#xff1b;2&#xff09;初始化对象中的属性&#xff1b;3&#xff…

类的构造函数和析构函数、默认构造函数

前言 程序只能通过成员函数来访问数据成员&#xff0c;因此需要设计合适成员函数&#xff0c;才能成功地将对象初始化。 类构造函数专门用于构造新对象&#xff0c;将值赋给他们的数据成员&#xff0c;进行初始化。 构造函数名称与类名相同&#xff0c;没有返回值&#xff0…

c++中的构造函数和析构函数

类和对象中&#xff0c;包括构造函数和析构函数&#xff0c;比较重要&#xff0c;通过学习总结一下&#xff0c;以便以后可以回顾&#xff01; 目录 构造函数 1.默认构造函数 2.有参构造函数 3.委托构造函数 4.复制(拷贝)构造函数 5.移动构造函数 左值引用与右值引用 析…

C++类构造函数和析构函数

11.3 类构造函数和析构函数 构造函数&#xff1a;是为了在定义对象时自动初始化其成员变量的值。 构造函数没有返回值&#xff0c;也没有被声明为void类型&#xff1b;因此&#xff0c;构造函数没有声明类型。 11.3.1 声明和定义一个构造函数 构造函数原型&#xff1a;在这…

C++ 构造函数和析构函数可以是虚函数嘛?

简单总结就是&#xff1a;构造函数不可以是虚函数&#xff0c;而析构函数可以且常常是虚函数。 构造函数不能是虚函数 1. 从vptr角度解释 虚函数的调用是通过虚函数表来查找的&#xff0c;而虚函数表由类的实例化对象的vptr指针(vptr可以参考C的虚函数表指针vptr)指向&#x…

构造函数和析构函数顺序

父子类 1、构造顺序&#xff1a; 创建一个子类对象&#xff0c;则父类、子类的构造方法都执行&#xff0c;且是 先父类 构造方法&#xff0c;再子类构造方法 派生类的构造顺序&#xff1a;先父类&#xff0c;后子类&#xff0c;因为子类很有可能会用到从父类继承来的成员 2、析…

【C++】构造函数与析构函数

1. 概述 构造函数&#xff1a;用于初始化对象&#xff0c;没有返回值&#xff0c;函数名和类名相同&#xff0c;只有在对象初始化的时候才会被调用。构造函数的分类&#xff1a; 默认构造函数&#xff1a;是编译器自动生成&#xff0c;没有任何参数的构造函数。 有参构造函数&…

何时调用构造函数和析构函数

何时调用构造函数和析构函数 构造函数的作用是保证每个对象的数据成员都有何时的初始值。 析构函数的作用是回收内存和资源&#xff0c;通常用于释放在构造函数或对象生命期内获取的资源。 一般我们都知道构造和析构的次序&#xff1a; 构造从类层次的最根处开始&#xff0c…

C++篇----构造函数和析构函数

在很多时候&#xff0c;当写了初始化&#xff0c;动态开辟的&#xff0c;需要写销毁函数&#xff0c;写了销毁函数之后&#xff0c;但是却忘记了调用这些函数&#xff0c;忘记调用初始化函数还好&#xff0c;编译器会报错&#xff0c;但是如果是忘记调用销毁函数&#xff0c;那…

c++构造函数和析构函数

一、构造函数和析构函数的特点 构造函数和析构函数是一种特殊的公有成员函数&#xff0c;每一个类都有一个默认的构造函数和析构函数&#xff1b;构造函数在类定义时由系统自动调用&#xff0c;析构函数在类被销毁时由系统自动调用&#xff1b;构造函数的名称和类名相同&#…

构造函数与析构函数

一&#xff0c;引言 由于c语言常常会忘记初始化与销毁&#xff0c;造成许多麻烦。所以c就引入了构造函数与析构函数&#xff0c;分别用来完成初始化与清理工作&#xff0c;且由编译器自动调用&#xff0c;这就避免了许多麻烦。 二&#xff0c;构造函数 构造函数是一个特殊的成…

构造函数和析构函数

文章目录 前言 1.构造函数<1>概念<2>特性 2.初始化列表<1>概念<2>特征 3.析构函数<1>概念<2.>特征 前言 如不清楚类的定义可以点击此篇文章&#xff1a;类的定义与引入 C为很么要引入构造函数和析构函数呢&#xff0c;前文讲到大佬引入了…

C++ 构造函数和析构函数 详解

目录 概述构造函数的分类1. 无参(默认)构造函数2. 有参构造函数3. 委托构造函数4. 复制(拷贝)构造函数5. 移动构造函数 构造函数调用规则析构函数 概述 C中用构造函数和析构函数来初始化和清理对象&#xff0c;这两个函数将会被编译器自动调用。对象的初始化和清理是非常重要的…

java异常处理及自定义异常

异常处理的实际上就是&#xff1a; 有风险的行为&#xff08;方法&#xff09;可能会将异常抛出&#xff08;throws&#xff09;。调用该方法的程序会尝试&#xff08;try&#xff09;去运行,运行的同时捕捉&#xff08;catch&#xff09;异常。 简而言之&#xff0c;就是对有…

java异常 — — 自定义异常

三、自定义异常 3.1、概述 为什么需要自定义异常类: Java中不同的异常类分别表示看某一种具体的异常情况&#xff0c;那么在开发中总是有些异常情况是SUN没有定义好的此时我们根据自己业务的异常情况来定义异常类。例如年龄负数问题&#xff0c;考试成绩负数问题等等。 在上…

JAVA自定义异常处理

自定义异常处理可以分为两种&#xff0c;一种是自定义编译处理&#xff0c;另一种是自定义运行处理 1.自定义编译处理需要创建一个异常类用于继承Exception类 重写构造器 在出现异常的地方用throw new 自定义对象抛出 作用&#xff1a;编译时异常时编译阶段就报错&#xff…

Java的自定义异常类

Java的异常处理机制可以让程序具有极好的容错性&#xff0c;让程序更加健壮。当程序运行出 现意外情形时&#xff0c;系统会自动生成一个 Exception对象来通知程序&#xff0c;从而实现将“业务功 能实现代码”和“错误处理代码”分离&#xff0c;提供更好的可读性。 Java把所…

Java自定义异常及统一处理,信息返回

开始操作 创建enums&#xff0c;exception包&#xff1a; enums包下&#xff1a; 创建BaseCodeEnum接口 创建Response类&#xff1a;为统一信息返回类 创建ResponseCode枚举类&#xff1a;在这里定义我们需要的异常 exception包下&#xff1a; 创建HandlerException类&#…

Java自定义异常类统一处理异常

当程序发生异常时&#xff0c;会返回一大堆不友好的内容&#xff0c;非常不美观&#xff01; 我们在写代码的时候&#xff0c;对异常处理一般是try catch或者抛出异常throws Exception。 try catch大家都知道&#xff0c;代码中大量的try catch会占用内存影响性能&#xff0c…