C++面向对象类的书写相关细节梳理

类的问题

继承类的原因:为了添加或者替换功能。

1. 继承时重写类的方法

v 替换功能

① 将所有方法都设置为virtual(虚函数),以防万一。

Virtual:经验表明最好将所有方法都设置为virtual,包括析构函数但不包括构造函数;

这样不必担心重写方法是否运行,这样做唯一的缺点是对性能具有轻微的影响;

即使某个类不大可能被扩展,最好还是将这个类的方法设置为virtual,以防万一。

② 重写方法的语法:在子类定义中重新声明这个方法,并在子类的实现文件中提供新的定义。(注意:方法定义中不需要重复使用virtual关键字)

③ 指针或者引用可以指向某个类的的对象或者子类的对象。例如:如果有一个对父类Super引用,而实际引用的是子类Sub对象,那么调用其中的方法实际上是调用子类版本的方法。

父类:Super类;

子类:Sub类;

Sub mySub;

Super& ref = mySub;

ref.someMethod();   //此处调用的是子类的someMethod()方法

如果在父类中省略了virtual关键字,重写功能将无法完成。

④ 即使父类的引用或者指针知道这实际上是一个子类,也无法访问没有在父类中定义的子类的方法或者成员。例如:

someOtherMethod( )是子类Sub的方法,父类没有该方法;

Sub mySub;

Super& ref = mySub;

Ref.someOtherMethod();     //BUG

mySub.someOtherMethod();  //可以执行

⑤ 非指针非引用对象是无法正确处理子类的特征信息。例如:

Sub mySub;

Super assignedObject = mySub;

assignedObject.someMethod();        //此处最多只会调用父类Super的someMethod()方法。

⑥ 总结:父类的指针或者引用指向子类对象时,子类保留其重写方法;但是如果通过类型转换将子类对象转换为超类对象,此时会丢失其特征,重写方法以及子类数据的丢失成为截断。

⑦ 将方法标记为final,这意味着无法在子类中重写这个方法。例如:

Virtual void someMethod() final;

2. 如何使用继承重用代码

v 在某个方法对于类的所有实例都相同时,便考虑将该方法设置为静态方法;

v

3. 利用父类

当编写一个子类时,需要知道父类以及子类之间的交互方式。创建顺序、构造函数链以及类型转换都是潜在的bug来源。

v 创建顺序

① 如果某个类具有基类,执行基类的默认构造函数。

② 类的非静态数据成员按照声明的顺序创建。

③ 执行该类的构造函数。

v 析构函数调用顺序

① 调用类的析构函数。

② 销毁类的数据成员,与创建的顺序想发。

③ 如果有父类,调用父类的析构函数。(所有析构函数都声明为virtual?????)

v 根据经验,所有析构函数都应该声明为virtual。例如:

v 从子类向父类传递构造函数的参数是正常的,但是无法传递数据成员。(如果这么做了,代码可以编译,但是记住在调用父类构造函数之后数据成员才会初始化,如果将数据成员作为参数传递给父类构造函数,数据成员不会被初始化。)

v 在子类中重写了父类中的某个方法时,如果想在重写方法中调用父类的该方法,一定要注意添加父类作用域,否则会执行无限循环。例如:

Sting MyWeatherPrediction::getTemperature( ) const

{

Return WeatherPrediction::getTemperature( )  + “F”;   //一定要在此处添加父类作用域

}

4.  父类、子类之间的转换

v 向上转型(即子类转父类)

当向上转型时,使用父类指针或者引用可以避免截断。

v 向下转型(即父类转子类),注意事项:

以上不实用,以下才是正确方法。

v 仅在必要的情况下才使用向下转型,并且一定要使用dynamic_cast。

继承与多态性

1. 类的多态性

v 在实际操作中,我们的代码是否很少用到类的多态性这一属性,实际上类的多态性是如此的好用。

以上的设计显示了让SpreadsheetCell层次结构具有多态性的方法。由于DoublSpreadsheetCell以及StringSpreadsheetCell都是从同一个父类SpreadsheetCell继承,从其他代码的角度来看,他们是可以互换的。实际上这意味着:

l 两个子类都支持由基类定义的同一接口(方法集)。

l 使用SpreadsheetCell对象的代码可以调用接口中的任何方法,而不需要知道这个单元格式是StringSpreadsheetCell还是DoublSpreadsheetCell。

l 由于虚方法的特殊能力,会根据对象所属的类调用接口中每个方法的正确实例。

l 其他数据结构可以通关过引用父类类型包含多种类型的单元格。

v 注意要合理的利用类的多态性这一属性,需要考虑以下一些问题:

① 在设计基类的时候,应该考虑子类之间的关系;根据这些信息,可以提取共有特性并将其放到父类中。

② 纯虚方法:纯虚方法在类定义中显示说明该方法不需要定义;因为这种基类是没有实例的(如果某个类包含了一个或者多个纯虚方法,那么就无法构建这种类型的对象);采用专门的语法指定纯虚方法:方法声明后紧接着=0;在.CPP文件中不需要编写任何代码。例如:

③ 抽象基类:以上提到的基类,便是抽象基类,是无法实例化的;但是可以使用抽象基类的指针或者引用,因为实际上指向的是子类对象。

抽象类提供了一种禁止其他代码直接实例化对象的方法,而它的子类可以实例化对象。

时间: 2024-09-15 16:35:58

C++面向对象类的书写相关细节梳理的相关文章

面向对象JS ES5/ES6 类的书写 继承的实现 new关键字执行 this指向 原型链

一 .什么是面向对象? 面向对象(Object Oriented),简写OO,是一种软件开发方法. 面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物. 面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统.交互式界面.应用结构.应用平台.分布式系统.网络管理结构.CAD技术.人工智能等领域. 面向对象是相对于面向过程来讲的,面向对象方法,把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式. 编程范式 一般可以

Scala笔记整理(四):Scala面向对象—类详解2(继承相关)

[TOC] 单例 希望某个类只存在一个使用的对象,而不管有多少个调用者在使用它,就是单例的概念. Java中的单例 package cn.xpleaf.single; /** * 单例模式-饿汉式(在属性中先创建好对象,不管是否调用getInstance方法) * @author yeyonghao * */ public class User { private static User user = new User(); private User(){} //外界调用不到构造函数 publi

【《代码整洁之道》精读与演绎】之五 整洁类的书写准则

本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/52344732 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 这篇文章将与大家一起聊一聊,书写整洁类的一些法则. 一.引言 以下引言的内容,有必要伴随这个系列的每一次更新,这次也不例外. <代码整洁之道>这本书提出了一个观点:代码质量与其整洁度成正比,干净的代码,既在质量上可靠,也为

512MB内存也流畅 Window10相关细节曝光

之前微软发布了最新的Windows10系统,并且将手机.平板和PC系统进行了统一.微软Windows Insider项目负责人Gabriel Aul刚刚就有关Windows10的相关问题向用户进行了分享. Window10相关细节曝光(图片引自nokiapoweruser) 据悉,第一版Windows10并不适用全部Windows Phone手机,不过之后的预览版会对更多机型进行支持,甚至包括512MB系统内存的机型,比如Lumia520.Lumia635等.Gabriel Aul称其目前日常用

~~核心编程(一):面向对象——类&amp;私有属性~~

进击のpython 面向对象--类&属性 虽然我们上一part写了一个面向对象的程序:人狗大战 但是如果在面向对象来看 你这些的就不够规范 你既然选择用面向对象的思想来写 那你就要符合人家的定义规范和操作流程 那废话不多说 开始整活! 走的太快,就要停下来等等灵魂! 前面是先整出一个模板是吧? 那咱们也写个模板! 按照面向对象的思想来写! 那 类 是不是就是模板!(为啥要分两个博客写,就是为了让你对照上一个来看的!) 那就涉及到知识盲区了吧! class Dog: # python中,类的书写首

java - 工具类 - 包装类,数字相关类, 日期相关类

工具类:java开发者写好的类 1.包装相关类 2.数字相关类 3.日期类 4.字符串 5.集合相关类 6.异常相关类 7.输入输出相关 IO(input/output) 8.线程 9.网络 10.注解 11.GUI 1.包装类: 为了将基本类型也面向对象,所以将他们分装进包装类中 1.byte -- Byte,short --Short,int -- Integer,long -- Long 2.float -- Float,double -- Double 3.char -- Charact

Php面向对象 – 类常量

类常量:类中,保存运行周期内,不变的数据. 定义: const关键字 const 常量名 = 常量值 例子: class Student { public  $stu_id; public  $stu_name; public  $stu_gender; const  GENDER_MALE = '男'; const  GENDER_FEMALE = '女'; } 类常量不受访问限定修饰符的限制 访问: 类::常量名 例子: class Student { public  $stu_id; pu

《转》面向对象类设计原则

面向对象类的设计原则 1                 SRP(单一职责原则) 这个原则看起来很简单,就是说一个类只能承担一个职责. 但这里有一个关键:"职责"是如何理解的? 按照汉语的理解,职责其实分为两部分:"职"和"责"."职"就是这个类是什么,而"责"就是这个类要干什么. 举个例子来说:Door是一个对象,那么它的"职"就是门,"责"就是"开门.关

java笔记--关于Object类与线程相关的方法

关于Object类中的线程方法 Object类是所有Java类的 父类,在该类中定义了三个与线程操作有关的方法,使得所有的Java类在创建之后就支持多线程 这三个方法是:notify(),notifyAll(),wait(),这几个方法都是用来控制线程的运行状态的. 方法列表如下: notify() : 唤醒在此对象监视器上等待的单个线程 notifyAll() : 唤醒在此对象监视器上等待的所有线程 wait() : 在其他线程时调用此对象的notify()或者notifyAll()方法前,导