《C++大学教程》学习笔记(十一)
2018-02-16 22:11
405 查看
《C++大学教程》学习笔记(十一)
1.继承
1.1实例
本章的内容不多,主要讨论的是面向对象编程(OOP)的另外一个关键特征:继承(inheritance)。继承是软件复用的一种方式,其中新类(“派生类”)吸收了现有类(“基类”)的数据和行为,并使这些类具有其他的新性能。由于书中的给出的实例实在是太为复杂,所以我自己捣鼓了一个实现继承的样例:基类为交通工具Vehicle,派生类为Car,我们先定义一个Vehicle类,再用后定义的Car类去public继承它。
下面给出实例的文件结构与具体代码:
Vehicle.hpp文件:
#ifndef Vehicle_hpp #define Vehicle_hpp #include <string> #include <iostream> #include <stdexcept> using namespace std; class Vehicle{ private: string brand; //品牌 int topSpeed; //最高速度 public: Vehicle(string,int); void setBrand(string); string getBrand() const; void setTopSpeed(int); int getTopSpeed() const; }; #endif /* Vehicle_hpp */
Vehicle.cpp文件:
#include "Vehicle.hpp" Vehicle::Vehicle(string b,int ts) :brand(b),topSpeed(ts) { //Nothing } void Vehicle::setBrand(string b){ brand = b; } string Vehicle::getBrand() const{ return brand; } void Vehicle::setTopSpeed(int ts){ if (ts > 0) topSpeed = ts; else throw invalid_argument("TopSpeed must > 0"); } int Vehicle::getTopSpeed() const { return topSpeed; }
Car.hpp文件:
#ifndef Car_hpp #define Car_hpp #include "Vehicle.hpp" //派生类Car通过public方式继承基类Vehicle class Car : public Vehicle{ private: int seats; //座位数 public: Car(string,int,int); void setSeats(int); int getSeats() const; void print() const; }; #endif /* Car_hpp */
Car.cpp文件:
#include "Car.hpp" //这里先直接调用基类的构造函数初始化基类的数据成员,再进行后续操作 Car::Car(string b,int ts,int s) : Vehicle(b,ts) { setSeats(s); } void Car::setSeats(int s){ if (s > 0) seats = s; else throw invalid_argument("seats must > 0"); } int Car::getSeats() const{ return seats; } void Car::print() const{ cout << "Brand:" << getBrand() << " TopSpeed:" << getTopSpeed() << " Seats:" << seats << endl; //在派生类中,无法直接访问基类的private成员,但可以通过调用基类的public成员函数来间接访问 }
main.cpp文件:
#include "Car.hpp" #include <iostream> using namespace std; int main(){ Car car1("BMW",200,5); Car car2("Ferrari",350,2); cout << "Car1 is a " << car1.getBrand() << endl << "Its top speed is " << car1.getTopSpeed() << "km/h\n" << "And it has " << car1.getSeats() << " seats\n\n"; cout << "Car2 is a " << car2.getBrand() << endl << "Its top speed is " << car2.getTopSpeed() << "km/h\n" << "And it has " << car2.getSeats() << " seats\n\n"; car1.print(); car2.print(); return 0; }
运行结果是:
从上面这个样例可以发现,即使派生类使用public方式来继承基类,也没有办法直接访问基类中的private成员,只能通过调用其基类的public成员函数(比如get与set函数)来间接访问private成员。这也从侧面反映C++ 中的private是一个很严格的属性。
那么有没有一种属性,它既不像public一样谁都可以碰,又没有private那样“小气”呢?
答案是肯定的,protected属性是介于public和private之间的一级保护。它可以在基类的定义及基类的友元中访问(这一点同private一样),但也能在基类的派生类中访问。
1.2其他要点
首先要说明的是,派生类是不会继承基类的构造函数的,但由于基类的构造函数必须声明为public,所以我们可以在派生类中随时访问。比如上面实例中的类Car构造函数://这里先直接调用基类的构造函数初始化基类的数据成员,再进行后续操作 Car::Car(string b,int ts,int s) : Vehicle(b,ts) { setSeats(s); }
在实例化派生类对象时,构造函数的调用顺序是先基类后派生类;
在销毁派生类的对象时,析构函数的调用顺序是先派生类后基类。
另外,当采用public、protected和private三种方式继承基类时,基类中的public、protected和private数据成员会有不用的变化,详情可以见书P383的表格。
相关文章推荐
- 《C++大学教程》学习笔记(九)
- 模式识别(Pattern Recognition)学习笔记(十一)--SVM支持向量机(狭义):大间隔
- Python学习笔记(十一)——正则表达式
- [置顶] Python3《机器学习实战》学习笔记(十一):线性回归基础篇之预测鲍鱼年龄
- 《设计模式精解》学习笔记(十一)------Decorator(装饰)模式
- Python学习笔记(十一)
- 《第一行代码-Android》学习笔记(十一)
- Android编程权威指南(第二版)学习笔记(十一)—— 第11章 使用 ViewPager
- 《设计模式之禅》学习笔记(十一)
- R 学习笔记《十一》 R语言初学者指南--图形工具(续)
- python学习笔记(十一)——算法与数据结构基础(算法概述+查找算法)
- 学习笔记十一:面向对象编程
- 模式识别(Pattern Recognition)学习笔记(十一)--SVM支持向量机(狭义):大间隔
- 《软件调试分析技术》学习笔记(十一)
- 《C++大学教程》学习笔记(十)
- 《TCP/IP详解》学习笔记(十一):TCP 交互数据流、成块数据流
- 《C++大学教程》学习笔记 第二章:C++编程入门
- 学习笔记(十一)服务
- 《C++大学教程》学习笔记(二、三)
- 《C++大学教程》学习笔记(七)