派生类构造函数

合集下载

C++派生类的构造函数

C++派生类的构造函数

前面我们说基类的成员函数可以被继承,可以通过派生类的对象访问,但这仅仅指的是普通的成员函数,类的构造函数不能被继承。

构造函数不能被继承是有道理的,因为即使继承了,它的名字和派生类的名字也不一样,不能成为派生类的构造函数,当然更不能成为普通的成员函数。

在设计派生类时,对继承过来的成员变量的初始化工作也要由派生类的构造函数完成,但是大部分基类都有private 属性的成员变量,它们在派生类中无法访问,更不能使用派生类的构造函数来初始化。

这种矛盾在C++继承中是普遍存在的,解决这个问题的思路是:在派生类的构造函数中调用基类的构造函数。

下面的例子展示了如何在派生类的构造函数中调用基类的构造函数:1.#include<iostream>ing namespace std;3.4.//基类People5.class People{6.protected:7.char*m_name;8.int m_age;9.public:10.People(char*,int);11.};12.People::People(char*name,int age):m_name(name),m_age(age){}13.14.//派生类Student15.class Student:public People{16.private:17.float m_score;18.public:19.Student(char*name,int age,float score);20.void display();21.};22.//People(name, age)就是调用基类的构造函数23.Student::Student(char*name,int age,float score):People(name, age),m_score(score){}24.void Student::display(){25.cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<"。

第5章 继承和派生类

第5章 继承和派生类
19
对类B的对象初始化即是对x,y,z,m,n等全部成员的初始化
5.4.2 私有继承
私有派生,派生类中基类的公有和保 护成员成为私有
class ClassName : private BaseClassName
私有派生时,基类中公有成员和保护成员在派生类 中均变为私有,在派生类中仍可直接使用这些成员,基 类中的私有成员,在派生类中不可直接使用。
15
从一个基类派生一个类的一般格式为:
class ClassName : <Access> BaseClassName
{ private: public:
派生类名 继承方式 基类名
......; //私有成员说明
......; //公有成员说明
protected:
派生类中新增加的成员
......; //保护成员说明
C++程序设计
主讲:王新祥
第5章 继承和派生类
2
5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9
继承与派生的概念 派生类的声明方式 派生类的构成 派生类成员的访问属性 派生类的构造函数和析构函数 多重继承 基类与派生类的转换 继承与组合 继承在软件开发中的重要意义
3
继承性是面向对象程序设计中最重要的机制。这 种机制提供了无限重复利用程序资源的一种途径。通 过C++语言中的继承机制,可以扩充和完善旧的程序 以适应新的需求。这样不仅可以节省程序开发的时间 和资源,并且为将来的程序增添了新的资源。
基类:public: 在派生类和类外都可以使用 protected: 在派生类中使用 private: 不能在派生类中使用
17
class A { int x; 因为y是基类保护,所以在派生类中可以 protected: int y; 直接引用。而在类外不可直接引用。 public: int z; A(int a, int b, int c) { x=a; y=b; z=c; } //基类初始化 int Getx() { return x; } //返回x int Gety() { return y; } //返回y void ShowA() { cout<< "x="<<x<<'\t'<<"y="<<y<<'\t'<<"z="<<z<<'\n'; } }; 因为z是基类公有,所以 公有派生 class B : public A { 在 派 生类 中和 类 外均 可 对基类初始化 int m, n; 直接引用。 public: B(int a, int b, int c, int d, int e) : A(a, b, c) { m=d; n=e; } void Show() { cout<<"m="<<m<<'\t'<<"n="<<n<<'\n'; cout<<"x="<<Getx()<<'\t'<<"y="<<y<<'\t'<<"z="<<z<<'\n'; } int Sum() { return (Getx()+y+z+m+n); } }; 因为x是基类私有,所以在派生类中和类外不能直接引用 void main(void) { B b1(1, 2, 3, 4, 5); b1.ShowA(); b1.Show(); cout<<"Sum="<<b1.Sum()<<'\n';cout<<"x="<<b1.Getx()<<'\t'; cout<<"y="<<b1.Gety()<<'\t'; cout<< "z="<<b1.z<<'\n'; } 18

C++第5章习题参考答案

C++第5章习题参考答案

1.什么是类的继承与派生?继承性是面向对象程序设计的第二个重要特性,通过继承实现了数据抽象基础上的代码重用。

继承是对许多问题中分层特性的一种自然描述,因而也是类的具体化和被重新利用的一种手段,它所表达的就是一种对象类之间的相交关系。

它使得某类对象可以继承另外一类对象的特征和能力。

继承所具有的作用有两个方面:一方面可以减少代码冗余;另一方面可以通过协调性来减少相互之间的接口和界面。

通过继承方式定义的子类也称为派生类。

2.类的三种继承方式之间的区别是什么?类的继承方式有public(公有)继承、protected(保护)继承和private(私有)继承三种。

对于不同的继承方式,会导致基类成员原来的访问属性在派生类中有所变化。

表5.1列出了不同继承方式下基类成员访问属性的变化情况。

表5.1 不同继承方式下基类成员的访问属性说明:该表第1列给出3种继承方式,第1行给出基类成员的3种访问属性。

其余单元格内容为基类成员在派生类中的访问属性。

从表中可以看出:(1) 基类的私有成员在派生类中均是不可访问的,它只能由基类的成员访问。

(2) 在公有继承方式下,基类中的公有成员和保护成员在派生类中的访问属性不变。

(3) 在保护继承方式下,基类中的公有成员和保护成员在派生类中均为保护的。

(4) 在私有继承方式下,基类中的公有成员和保护成员在派生类中均为私有的。

需要注意的是:保护成员与私有成员唯一的不同是当发生派生后,处在基类protected区的成员可被派生类直接访问,而私有成员在派生类中是不可访问的。

在同一类中私有成员和保护成员的用法完全一样。

3.派生类能否直接访问基类的私有成员?若否,应如何实现?派生类不能直接访问基类的私有成员。

具体实现方式:(1) 在类定义体中增加保护段为了便于派生类的访问,可以将基类私有成员中需提供给派生类访问的部分定义为保护段成员。

保护段成员可以被它的派生类访问,但是对于外界是隐藏起来的。

这样,既方便了派生类的访问,又禁止外界对它的派生类访问。

C++试题及答案

C++试题及答案

C++程序设计模拟试卷(一)一、单项选择题(本大题共20小题,每小题1分,共20分)在每小题列出的四个备选项中只有一个是符合题目要求的,请将其代码填写在题后的括号内。

错选、多选或未选均无分。

1. 编写C++程序一般需经过的几个步骤依次是()A. 编辑、调试、编译、连接B。

编辑、编译、连接、运行C. 编译、调试、编辑、连接D. 编译、编辑、连接、运行答案:B解析:经过编辑、编译、连接和运行四个步骤。

编辑是将C++源程序输入计算机的过程,保存文件名为cpp。

编译是使用系统提供的编译器将源程序cpp生成机器语言的过程,目标文件为obj,由于没有得到系统分配的绝对地址,还不能直接运行。

连接是将目标文件obj转换为可执行程序的过程,结果为exe。

运行是执行exe,在屏幕上显示结果的过程.1.基类的构造函数。

2.子对象的构造函数。

3.成员初始化表中的其他项.4.派生类构造函数的函数体。

2。

决定C++语言中函数的返回值类型的是()A。

return语句中的表达式类型B。

调用该函数时系统随机产生的类型C。

调用该函数时的主调用函数类型D. 在定义该函数时所指定的数据类型答案:D解析:函数的返回值类型由定义函数时的指定的数据类型决定的.A项的表达式的值要转换成函数的定义时的返回类型.3。

下面叙述不正确的是()A。

派生类一般都用公有派生B。

对基类成员的访问必须是无二义性的C. 赋值兼容规则也适用于多重继承的组合D. 基类的公有成员在派生类中仍然是公有的答案:D解析:继承方式有三种:公有、私有和保护.多继承中,多个基类具有同名成员,在它们的子类中访问这些成员,就产生了二义性,但进行访问时,不能存在二义性。

赋值兼容规则是指派生类对象可以当作基类对象使用,只要存在继承关系,所以单继承或多继承都适用。

基类中的公有成员采用私有继承时,在派生类中变成了私有成员,所以D项错误.4。

所谓数据封装就是将一组数据和与这组数据有关操作组装在一起,形成一个实体,这实体也就是()A。

面向对象程序设计 四

面向对象程序设计 四
第四章 派生类与继承
• 4.1 派生类的概念 • 4.2 派生类的构造函数和析构函数 • 4.3 调整基类成员在派生类中的访问属性的 其他方法 • 4.4 多重继承 • 4.5 赋值兼容规则
第四章 派生类与继承
继承允许在既有类的基础上创建新的类,新类可以从 一个或多个既有类中继承数据和函数,而且可以重新定义 或加进新的数据和函数。 假设有两个类---类A 和类B,若类B继承类A,则类B 具有类A的基本特性(包括数据和程序代码) A (基类或父类) B (派生类或子类)
(3)基类中的保护成员:
当继承方式为公有继承时,基类中的保护成员在派生类中为保护成员 当继承方式为私有继承时,基类中的公有成员在派生类中为私有成员 当继承方式为保护继承时,基类中的公有成员在派生类中为保护成员
4.1 派生类的概念
4.1.4 派生类对基类成员的访问规则 派生类对基类成员的访问形式: (1)内部访问:由派生类中新增成员对基类继承来的成员的访问。 (2)对象访问:在派生类外部,通过派生类的对象对从基类继承来的 成员的访问。 派生类对基类成员的访问规则 (1)私有继承的访问规则 (2)公有继承的访问规则 (3)保护继承的访问规则
4.2 派生类的构造函数和析构函数
在类间实现继承时,虽然派生类继承了基类的成员,从而实现了 原代码的重用,但由于基类的构造函数和析构函数不能被继承 基类的构造函数和析构函数不能被继承,因此 基类的构造函数和析构函数不能被继承 在派生类中,如果对派生类新增的成员进行初始化,就需要加入派生 类的构造函数。 同时,对所有从基类继承下来的成员的初始化工作,还是由基类 的构造函数来完成,但是我们必须在派生类中对基类的构造函数所需 必须在派生类中对基类的构造函数所需 要的参数进行设置。 要的参数进行设置 同样,对撤销派生类对象时的扫尾、清理工作也需要加入新的析 构函数来完成。

构造函数的执行顺序

构造函数的执行顺序

构造函数的执⾏顺序⼀、C#中构造函数有⼏种。

1.静态构造函数2.默认构造函数3.带参数的构造函数⼆、顺序如何执⾏呢?先看代码:class MyClass{static MyClass(){Console.WriteLine("静态构造函数被调⽤。

");}private static Component staticField = new Component("静态字段被实例化。

");private Component instanceField = new Component("实例成员字段被实例化。

");public MyClass(){Console.WriteLine("对象构造函数被调⽤。

");}}//此类型⽤于作MyClass类的成员//此类型在实例化的时候可以再控制台输出⾃定义信息,以给出相关提⽰class Component{public Component(String info){Console.WriteLine(info);}}class Program{static void Main(string[] args){MyClass instance = new MyClass();Console.Read();}} 运⾏结果:1.静态字段被实例化2.静态构造函数被调⽤3.实例成员字段被实例化4.对象构造函数被调⽤再来看看带基类的构造函数是如何运⾏class Base{static Base(){Console.WriteLine("基类静态构造函数被调⽤。

");}private static Component baseStaticField = new Component("基类静态字段被实例化。

");private Component baseInstanceField = new Component("基类实例成员字段被实例化。

构造函数的作用是在创建对象时

构造函数的作用是在创建对象时
都可以用于函数参数和返回值。
二,对象数组
1.定义格式:
2.对象数组元素:
3.区别:指向对象数组的指针和对象指针数组。
三,子对象和堆对象
子对象概念:一个对象作为另一个类的成员时,该对象称为类的子对象。子对象实际是某类的数据成员。
堆对象:在程序运行中,根据需要随时创建的对象称为堆对象。
C++中,内存被分为4种储存区域:
该运算符必须用于由new返回的指针。
对于一个指针只能使用一次运算符delete。
指针名前只能使用一对方括号,而不管所释放数组的为数,并且方括号内不写任何东西。
该运算符也适应于空指针。
四,类型转换和转换函数
类型转换包括隐含类型转换和强制类型转换。转换函数是一种强制类型转换。
单参数的构造函数,提供了一种功能,可以将其他数据类型的数值或变量转换为用户所定义的数据类型。这便是单参数构造函数所具有的类型转换功能。
动态联编:指在程序运行时进行的联编,又称晚期联编。
继承是动态联编的基础,虚函数是动态联编的关键。
三,动态联编的条件
公有继承
虚函数
引用虚函数的方法:对象引用和对象指针、成员函数。
虚函数的特性:
派生类中的虚函数与基类中的虚函数具有相同的参数个数、对应的参数类型,相同的返回值类型。
基类中说明的虚函数具有自动向下传给他的派生类的性质。即派生类的虚函数中的virtual说明可以省略。
基类构造函数。
子对象构造函数。
派生类构造函数。
派生类析构函数的调用顺序:
先调用派生类的析构函数。
在调用派生类中子对象的析构函数。
最后调用基类的析构函数。
在基类中定义有默认构造函数或者没有定义任何构造函数时,派生类构造函数中省略对基类构造函数的调用。

c++派生类的构造函数

c++派生类的构造函数

c++派生类的构造函数C++是一门面向对象的编程语言,它允许程序员使用类和对象来封装数据和行为。

在C++中,派生类是基于已存在的类(称为基类)创建的一种新类。

派生类从基类继承了数据和方法,并且还可以添加新的属性和方法。

在C++中,派生类的构造函数是指创建派生类对象时所调用的函数。

派生类的构造函数负责初始化派生类对象中从基类继承的成员和派生类自己添加的成员。

本文将详细介绍C++派生类的构造函数。

在C++中,派生类的构造函数必须调用基类的构造函数,以初始化从基类继承的成员变量。

在创建派生类对象时,首先创建基类对象,然后再对派生类对象进行初始化。

1. 构造函数必须有与类名相同的名称。

2. 构造函数可以有参数,也可以没有参数。

3. 派生类必须调用基类的构造函数,以初始化从基类继承的成员变量。

下面是一个基类Person和一个派生类Student的定义:```cppclass Person{protected:string name;int age;public:Person(){}void setName(string n){name = n;}void setAge(int a){age = a;}};在定义派生类Student的时候,通过public继承了基类Person。

此时,派生类的构造函数必须调用基类的构造函数,以初始化从基类继承的成员变量name和age。

派生类新增加了一个成员变量grade,需要在自己的构造函数中进行初始化。

派生类构造函数可以有多种调用方式,具体如下:1. 用基类构造函数初始化列表初始化派生类对象初始化列表是C++语言提供的一种简洁的初始化成员变量的语法。

它使用冒号(:)后接一个以逗号分隔的初始化列表,在其中对派生类和基类成员变量进行初始化。

下面是Student类中使用初始化列表对基类成员变量进行初始化的方法:在上面的代码中,派生类Student的构造函数使用冒号后接一个初始化列表来初始化基类成员变量name和age。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

派生类构造函数
派生类的数据成员由所有基类的数据成员与派生类新增的数据成员共同组成,如果派生类新增成员中包括其他类的对象(子对象),派生类的数据成员中实际上还间接包括了这些对象的数据成员。

因此,构造派生类的对象时,必须对基类数据成员、新增数据成员和成员对象的数据成员进行初始化。

派生类的构造函数必须要以合适的初值作为参数,隐含调用基类和新增对象成员的构造函数,来初始化它们各自的数据成员,然后再加入新的语句对新增普通数据成员进行初始化。

派生类构造函数的一般格式如下:
<派生类名>::<派生类名>(<参数表>) : <基类名1>(<参数表1>),
……,
<基类名n>(<参数表n>),
<子对象名1>(<参数表n+1>),
……,
<子对象名m>(<参数表n+m>)
{
<派生类构造函数体> //派生类新增成员的初始化
}
说明:
(1) 对基类成员和子对象成员的初始化必须在成员初始化列表中进行,新增成员的初始化既可以在成员初始化列表中进行,也可以在构造函数体中进行。

(2) 派生类构造函数必须对这三类成员进行初始化,其执行顺序如下所述。

. 调用基类构造函数;
. 调用子对象的构造函数;
. 派生类的构造函数体;
(3) 当派生类有多个基类时,处于同一层次的各个基类的构造函数的调用顺序取决于定义派生类时声明的顺序(自左向右),而与在派生类构造函数的成员初始化列表中给出的顺序无关。

(4) 如果派生类的基类也是一个派生类,则每个派生类只需负责其直接基类的构造,依次上溯。

(5) 当派生类中有多个子对象时,各个子对象构造函数的调用顺序也取决于在派生类中定义的顺序(自前至后),而与在派生类构造函数的成员初始化列表中给出的顺序无关。

(6) 派生类构造函数提供了将参数传递给基类构造函数的途径,以保证在基类进行初始化时能够获得必要的数据。

因此,如果基类的构造函数定义了一个或多个参数时,派生类必须定义构造函数。

(7) 如果基类中定义了缺省构造函数或根本没有定义任何一个构造函数(此时,由编译器自动生成缺省构造函数)时,在派生类构造函数的定义中可以省略对基类构造函数的调用,即省略"<基类名>(<参数表>)"。

(8) 子对象的情况与基类相同。

(9) 当所有的基类和子对象的构造函数都可以省略时,可以省略派生类构造函数的成员初始化列表。

(10) 如果所有的基类和子对象构造函数都不需要参数,派生类也不需要参数时,派生类构造函数可以不定义。

(11) 派生类不能继承基类的构造函数和析构函数。

相关文档
最新文档