一、前言

  好吧,本系列博客已经变成了《C++ Primer Plus》的读书笔记,尴尬。在使用C语言时,多通过添加库函数的方式实现代码重用,但有一个弊端就是原来写好的代码并不完全适用于现在的情况。OOP设计思想中类的继承相比来说更为灵活,可以添加新的数据成员和方法,也能修改继承下来方法的实现细节,同时还保留了原有的代码。开始进入正题。

二、类继承示例

  场景如下:现需要记录乒乓球运动成员的信息,包括姓名和有无空余桌台。其中有一部分成员参加过比赛,需要将这一部分单独提出并记录他们在比赛中的比分。因此,参加过比赛的成员所属的类就是素有成员所属类的派生类对象了。

类声明:

 #ifndef TABTENN_H_
#define TABTENN_H_ #include <string> using std::string; class TableTennisPlayer
{
private:
string firstname;
string lastname;
bool hasTable; public:
TableTennisPlayer (const string& fn = "none",
const string& ln = "none",bool ht = false);
void Name() const;
bool HasTable() const {return hasTable;};
void ResetTable(bool v) {hasTable = v;};
}; //derived class
class RatedPlayer:public TableTennisPlayer //TableTennisPlayer是基类
{
private:
unsigned int rating;
public:
RatedPlayer(unsigned int r = ,const string& fn = "none",const string& ln = "none",
bool ht = false);//默认构造函数
RatedPlayer(unsigned int r,const TableTennisPlayer& tp);//通过基类对象创建派生类对象构造函数
unsigned int Rating() const {return rating;}
void ResetRating (unsigned int r) {rating = r;}
}; #endif

tabtenn.h

类方法定义:

 #include <iostream>
#include "tabtenn.h" TableTennisPlayer::TableTennisPlayer (const string& fn,const string& ln,bool ht):
firstname(fn),lastname(ln),hasTable(ht)//成员初始化列表
{} void TableTennisPlayer::Name() const
{
std::cout << lastname << ", " << firstname;
} //RatedPlayer methods
//派生类构造函数必须调用基类构造函数
RatedPlayer::RatedPlayer(unsigned int r,const string& fn,const string& ln,bool ht):
TableTennisPlayer(fn,ln,ht)//派生类构造函数首先创建基类对象,使用初始化列表完成
{
rating = r;
} RatedPlayer::RatedPlayer(unsigned int r,const TableTennisPlayer& tp):
TableTennisPlayer(tp),rating(r)
{}

tabtenn.cpp

  上述代码将基类TableTennisPlayer和派生类RatedPlayer放在了一起。RatedPlayer类声明中使用:public name_of_base_class 表示公有派生。在派生类的声明中要添加自己的构造函数和额外的成员函数和方法。这里派生类构造函数中学问很大。

  在创建派生类对象之前必须先创建基类对象,这是因为派生类的方法无法直接访问基类的私有成员。那问题来了:当创建新的派生类对象时,会自动调用派生类构造函数。如何实现在调用派生类构造函数之前就调用基类构造函数创建基类对象呢?(好绕口)这里需要使用构造函数的特有语法——初始化列表。在程序指针指向派生类构造函数大括号内第一行之前即在初始化列表中完成了基类构造函数的调用。为了方便从基类对象中直接选出派生类对象(基类对象包含派生类对象),使用第二个构造函数,直接为基类对象添加比分信息获得。

三、应用程序示例

应用程序代码:

 #include <iostream>
#include "tabtenn.h" using std::endl;
using std::cout; int main()
{
TableTennisPlayer player1("Tara","Boomdea",false);//创建基类对象
RatedPlayer rplayer1(,"Mallory","Duck",true);//创建派生类对象
player1.Name();
if(player1.HasTable())
cout << ": has a table.\n";
else
cout << ": hasn't a table.\n";
rplayer1.Name();
if(rplayer1.HasTable())
cout << ": has a table.\n";
else
cout << ": hasn't a table.\n"; //initialize RatedPlayer using TableTennisPlayer object
RatedPlayer rplayer2(,player1);
cout << "Name: ";
rplayer2.Name();
cout << ";Rating: " << rplayer2.Rating() << endl;
return ;
}

usett.cpp

   player和rplayer分别代表基类对象和派生类对象。rplayer2和player1其实是同一个人,本来参加过比赛的成员就是从所有成员中挑选出来的。应用该程序比较简单,这里就不过多描述了。

C++基础——类继承的更多相关文章

  1. C++基础——类继承中方法重载

    一.前言 在上一篇C++基础博文中讨论了C++最基本的代码重用特性——类继承,派生类可以在继承基类元素的同时,添加新的成员和方法.但是没有考虑一种情况:派生类继承下来的方法的实现细节并不一定适合派生类 ...

  2. java基础 类 & 继承

    类 在Java中,类文件是以.java为后缀的代码文件,在每个类文件中可以有多个类,但是最多只允许出现一个public类,当有public类的时候,类文件的名称必须和public类的名称相同,若不存在 ...

  3. C#核心基础--类的继承

    继承 一个类可以继承自另一个类.在 C#中,类与类之间只存在单一继承.也就是说,一个类的直接基类只能有一个.当类与类之间实现继承的时候,子类可以将它的直接基类的所有成员当做自己的成员,除了类的静态构造 ...

  4. Python基础(十一) 类继承

    类继承: 继承的想法在于,充份利用已有类的功能,在其基础上来扩展来定义新的类. Parent Class(父类) 与 Child Class(子类): 被继承的类称为父类,继承的类称为子类,一个父类, ...

  5. Python 基础 类的继承

    如果寂静定义了Person类,需要定义新的Student 和Teacher 类时 可以直接从Person 中继承 class Person(Object): def __init__(self,nam ...

  6. Day 18 :面向对象[基础,继承,组合]类的增删改查

    有的人说,编程有3种范式: 1.面向过程:就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了. 2.面向函数:面向函数是面向过程的升级版,也就是把每个 ...

  7. python基础——类和实例

    python基础——类和实例 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都 ...

  8. Javascript类继承-机制-代码Demo【原创】

    最近看到<Javascript设计模式>,对js模拟的”继承方式“有了更深一步的了解,虽然之前也总是用到prototype.new ,但只是知其然不知所以然,现在将类继承的方法整理如下,暂 ...

  9. smartjs 0.2 OOP讲解 - Klass 类继承

    SmartJS2.0加入OOP的功能.OOP包括klass与factory两个对象. Klass 类继承 与其他的类继承相比,smartjs使用了执行指针的概念(后面例子中会介绍),另外提供base基 ...

随机推荐

  1. (细节)My SQL中主键为0和主键自排约束的关系

    开始不设置主键 表的设计如下: 如果id的位置有好几个0的话:设置主键并且自动排序时,0会从1开始递增: Insert 进去 id = 0的数据,数据会从实际的行数开始增加,和从0变化不一样: 现在主 ...

  2. ZooKeeper的使用---Java程序

    一.导入库 以下库存放在目录lib中: audience-annotations-0.5.0.jar jline-0.9.94.jar log4j-1.2.17.jar netty-3.10.6.Fi ...

  3. css3D的魅力

    前言: 最近玩了玩用css来构建3D效果,写了几个demo,所以博客总结一下.  在阅读这篇博客之前,请先自行了解一下css 3D的属性,例如:transform-style,transform-or ...

  4. Python /usr/bin/python

    #!/usr/bin/python是告诉操作系统执行这个脚本的时候,调用/usr/bin下的python解释器: #!/usr/bin/env python这种用法是为了防止操作系统用户没有将pyth ...

  5. codeforces 985C Liebig's Barrels

    题意: 有n * k块木板,每个木桶由k木板组成,每个木桶的容量定义为它最短的那块木板的长度. 任意两个木桶的容量v1,v2,满足|v1-v2| <= d. 问n个木桶容量的最大的和为多少,或者 ...

  6. Eureka-服务注册与发现组件

    一.Eureka是Netflix开发的服务组件 本身是一个基于REST的服务,Spring Cloud将它集成在其子项目spring-cloud-netflix中,以实现Spring cloud的服务 ...

  7. go语言nsq源码解读六 tcp.go、tcp_server.go

    本篇讲nsqlookupd中tcp.go.tcp_server.go tcp_server.go位于util目录下. 12345678910111213141516171819202122232425 ...

  8. bzoj 2588 树上主席树

    主席树上树,对于每个节点,继承其父亲的,最后跑f[x]+f[y]-f[lca]-f[fa[lca]] 去重竟然要减一,我竟然不知道?? #include<cstdio> #include& ...

  9. BZOJ_5180_[Baltic2016]Cities_ 斯坦纳树

    BZOJ_5180_[Baltic2016]Cities_ 斯坦纳树 题意: 给定n个点,m条双向边的图.其中有k个点是重要的.每条边都有一定的长度. 现在要你选定一些边来构成一个图,要使得k个重要的 ...

  10. BZOJ_1097_[POI2007]旅游景点atr_状压DP

    BZOJ_1097_[POI2007]旅游景点atr_状压DP 题面描述: FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣 的事情.经过这些城市的顺 ...