C加加中是否要编写C语言对基类和成员对象的析构函数的调用

面向对象程序设计杜茂康答案

适鼡专业:计算机科学与技术专业、软件工程专业

预修课程:《计算机导论》、《

语言程序设计》、《数据结构》

是计算机科学与技术专业、软件工程专业的一

门专业基础课面向对象软件开发方法是吸收了软件工程领域有益

的概念和有效的方法而发展起来的一种软件开发方法。它把数据和

对数据的操作封装起来集抽象性、封装性、继承性和多态性于一

体,可以帮助人们开发出模块化、数据抽象程度高的、體现信息隐

蔽、可复用、易修改、易扩充等特性的程序面向对象程序设计方

法及技术是对面向对象方法及思想的基本体现。

语言的基本概念、语法规则和面向对象的程序设计方

语言中的面向对象机制为主学习者在学习过程

中可以通过大量的程序实例和相关练习,逐步掌握

的功能从而掌握面向对象程序设计的基本知识和基本技能,学会

语言进行一般面向对象程序的设计解决一般应用问题,

并为后续专業课程的学习奠定程序设计基础

北京:北京邮电大学出版社,

北京:清华大学出版社

面向对象程序设计题解与上机指导》

15.1、面向对象编程:概述

         在C++中多態性仅用于通过继承而相关联的类型的引用或指针,通过基类的引用(或指针)调用虚函数时发生动态绑定。

15.2、定义基类和派生类

如果┅个调用省略了具有默认值的实参则所有的值由调用该函数的类型定义,与对象的动态类型无关即通过基类的引用或指针调用虚函数時,默认实参为在基类虚函数声明中指定的值如果通过派生类的指针或引用调用虚函数,则默认实参是在派生类的版本中声明的值

15.2.5、公有、私有和受保护的继承

struct和class除了默认成员访问保护级别,没有其他区别使用class保留字定义的派生类默认具有private继承,而struct保留字定义的类默認具有public继承如可以struct

         派生类可以恢复继承成员的访问级别,但不能使访问级别比基类中原来指定的更严格或更宽松通过用using A::成员名。成员洺可以是函数名如A中有size()成员函数,可以usingA::size;使得私有继承的A在子类中可以还原成A中size()的访问级别

15.3.1、派生类到基类的转换

         将对象传给希望接受引用是的函数时,引用直接绑定到该对象实参实际上是该对象的引用,对象本身未被复制该对象仍是派生类型对象。将派生类对象传給希望接受基类类型对象(而不是引用)的函数时该派生类对象的基类部分被复制到形参

         如果是public继承则用户代码和后代类都可以使鼡派生类到基类的转换。如果类是使用private或protected继承派生的则用户不能将派生类型对象转换为基类对象。对于后代类如果是private则也不能转换,洳果是protected继承则可以。

15.4、构造函数和复制控制

     构造函数初始化列表为类的基类和成员提供初始值它并不指定初始化的执行次序。首先初始化基类然后根据声明次序初始化派生类的成员。

     重构包括重新定义类层次将操作和/或数据从一个类移到另一个类。

     构造函数只能初始化其直接基类的原因是每个类都定义了自己的接口与该类的所有交互都应该通过该接口,即使对象是派生类对象的一部分也不例外(初始化列表指定父类的父类构造函数是错误的)。

15.4.3、复制控制和继承

     派生类析构函数不负责撤销基类对象的成员它只负责清除自己的荿员。对象撤销顺序与构造顺序相反:首先运行派生类析构函数然后按继承层次依次向上调用各基类析构函数。

     基类析构函数是三法则(如果类需要析构函数则类几乎也确实需要其他复制控制函数13.3节)的一个重要例外。如果基类为了将析构函数设为虚函数而具有空析构函数那么,类具有析构函数并不表示也需要赋值操作符或复制构造函数

     构造函数不能定义为虚函数,因为在构造函数运行时对象的动態类型还不完整

15.4.5、构造函数和析构函数中的虚函数

     如果在构造函数或析构函数中调用虚函数,则运行的是为构造函数或析构函数自身类型定义的版本(因为构造和析构时,类对象不完整)

15.5、继承情况下的类作用域

15.5.1、名字查找在编译时发生

     基类类型的指针(引用或对象)呮能访问对象的基类部分(多态前提是基类中有派生类的方法(虚函数))。

15.5.2、名字冲突与继承

     与基类成员同名的派生类成员将屏蔽对基类成员的直接访问

15.5.3、作用域与成员函数

     在基类和派生类中使用同一名字的成员函数,会屏蔽基类成员即使函数原型不同(如f()和f(int))也會屏蔽。

     如调用f()在派生类中,一旦找到函数名(f(int))编译器就不再继续查找了(不会去基类中找),调用方法定义不匹配则出错。

     如果函数是虚函数且通过引用或指针调用则编译器生成代码以确定根据对象的动态类型运行哪个版本,否则编译器生成代码直接调用函數。

将这三个类对象指针传递给Base指针则D1的Base指针调用f()是Base的f(),而D2成功实现多态

  含有(或继承)一个或多个纯虚函数的类是抽象基类。除了莋为抽象基类的派生类的对象的组成部分不能创建抽象类型的对象。

  因为派生类对象在赋值给基类对象时会被“切掉”所以容器与通過继承相关的类型不能很好融合。

  可以显示地将基类对象强制转换为派生类对象并将结果对象加入容器

15.8、句柄类与继承

  句柄类存储和管悝基类指针。

  对于赋值操作符将右操作数的使用计数加1并复制指针,并且首先必须将左操作数的使用计数减1如果使用计数减至0就删除指针。(因此这边特别要注意自身赋值可以先将右操作数的使用计数加1)。

单向链表的反转是一个经常被问箌的一个面试题也是一个非常基础的问题。比如一个链表是这样的: 1->2->3->4->5 通过反转后成为5->4->3->2->1

最容易想到的方法遍历一遍链表,利用一个辅助指针存储遍历过程中当前指针指向的下一个元素,然后将当前节点元素的指针反转后利用已经存储的指针往后面继续遍历。源代码如丅:

还有一种利用递归的方法这种方法的基本思想是在反转当前节点之前先调用递归函数反转后续节点。源代码如下不过这个方法有┅个缺点,就是在反转后的最后一个结点会形成一个环所以必须将函数的返回的节点的next域置为NULL。因为要改变head指针所以我用了引用。算法的源代码如下:

尝试写出类的成员函数实现

一种O(n)的办法就是(搞两个指针,一个每次递增一步一个每次递增两步,如果有环的話两者必然重合反之亦然):

我要回帖

更多关于 c语言编程 的文章

 

随机推荐