当前课程知识点:程序设计基础(下) > 拓展学习 > 继承与多态应用实例 > 继承与多态应用实例
应用实例
【例1】定义一个Document类,有数据成员m_name。从Document派生出Book类,增加数据成员m_pageCount。
#include <iostream>
#include <string>
using namespace std;
class Document
{
public:
Document() {}
Document(char *);
void PrintName();
private:
char *m_name;
};
Document::Document(char *pName)
{
m_name=new char[strlen(pName)+1];
strcpy(m_name,pName);
}
void Document::PrintName()
{
cout<<m_name<<endl;
}
class Book : public Document
{
public:
Book(char *,long);
void PrintName();
private:
long m_pageCount;
};
Book::Book(char *pName,long page) : Document(pName)
{
m_pageCount=page;
}
void Book::PrintName()
{
cout<<"Name of book is ";
Document::PrintName();
}
int main()
{
Document d("Document1");
Book b("Book1",300);
b.PrintName();
return 0;
}
运行结果为: Name of book is Book1
【例2】下面的范例要显示Shape、Point、Circle、Cylinder类的层次结构。
类层次分析:
这里类的层次结构的顶层是抽象基类Shape。Shape类中有一个纯虚函数PrintShapeName()和Print(),所以它是一个抽象基类。类Shape中还包含其他两个虚函数Area()和Volume(),它们都有默认的实现(返回0值)。类Point从Shape类中继承了这两个函数的实现,由于点的面积和体积是0,所以这种继承是合理的。Circle类从Point类中继承了函数Volume(),但Circle本身提供了函数Area()的实现。Cylinder对函数Area()和Volume()提供了自己的实现。
注意,尽管Shape是一个抽象基类,但是仍然可以包含某些成员函数的实现,并且这些实现是可继承的。Shape类以四个虚函数的形式提供了一个可继承的接口)类层次结构中的所有类都将包含这些虚函数)。
//Shape.h
#ifndef SHAPE_H
#define SHAPE_H
class Shape
{
public:
virtual double Area(){ return 0.0; }
virtual double Volume(){ return 0.0; }
// 纯虚函数
virtual void PrintShapeName() = 0;
virtual void Print() = 0;
};
#endif
//Point.h
#ifndef POINT_H
#define POINT_H
#include <iostream>
using namespace std;
#include "shape.h"
class Point : public Shape
{
public:
Point( int = 0, int = 0 ); // 缺省构造函数
void SetPoint( int, int );
int GetX() const { return m_x; }
int GetY() const { return m_y; }
virtual void PrintShapeName(){ cout << "Point: "; }
virtual void Print();
private:
int m_x, m_y; // 点的x,y坐标
};
#endif
//point.cpp
#include "point.h"
#include <iostream>
using namespace std;
Point::Point( int x, int y )
{
SetPoint( x, y );
}
void Point::SetPoint( int x, int y )
{
m_x = x;
m_y = y;
}
void Point::Print()
{
cout << "(" << m_x << ", "<< m_y << ")";
}
//Circle.h
#ifndef CIRCLE_H
#define CIRCLE_H
#include "point.h"
class Circle : public Point
{
public:
Circle( double r = 0.0, int x = 0, int y = 0 );
void SetRadius( double );
double GetRadius();
virtual double Area();
virtual void PrintShapeName(){ cout << "Circle: "; }
virtual void Print();
private:
double m_radius; // 圆的半径
};
#endif
//Circle.cpp
#include <iostream>
using namespace std;
#include "circle.h"
Circle::Circle( double r, int a, int b ) : Point( a, b ) // 调用基类构造函数
{
SetRadius( r );
}
void Circle::SetRadius( double r )
{
m_radius = r > 0 ? r : 0;
}
double Circle::GetRadius()
{
return m_radius;
}
double Circle::Area()
{
return 3.14159 * m_radius * m_radius;
}
void Circle::Print()
{
Point::Print();
cout << "; Radius =" << m_radius;
}
//Cylinder.h
#ifndef CYLINDER_H
#define CYLINDER_H
#include "circle.h"
class Cylinder : public Circle
{
public:
Cylinder( double h = 0.0, double r = 0.0, int x = 0, int y = 0 );
void SetHeight( double );
double GetHeight();
virtual double Area();
virtual double Volume();
virtual void PrintShapeName(){cout << "Cylinder: ";}
virtual void Print();
private:
double m_height; // 圆柱体的高
};
#endif
//Cylinder.cpp
#include <iostream>
using namespace std;
#include "cylinder.h"
Cylinder::Cylinder( double h, double r, int x, int y ): Circle( r, x, y ) // 调用基类构造函数
{
SetHeight( h );
}
void Cylinder::SetHeight( double h )
{
m_height = h > 0 ? h : 0;
}
double Cylinder::GetHeight()
{
return m_height;
}
double Cylinder::Area()
{
// 圆柱体表面积
return 2 * Circle::Area() + 2 * 3.14159 * GetRadius() * m_height;
}
double Cylinder::Volume()
{
return Circle::Area() * m_height;
}
void Cylinder::Print()
{
Circle::Print();
cout << "; Height =" << m_height;
}
//test.cpp
#include <iostream>
#include <iomanip>
#include "shape.h"
#include "point.h"
#include "circle.h"
#include "cylinder.h"
void virtualViaPointer( Shape * );
void virtualViaReference( Shape & );
int main()
{
cout << setiosflags( ios::fixed | ios::showpoint ) << setprecision( 2 );
Point point( 7, 11 ); // 创建一个点的对象
Circle circle( 3.5, 22, 8 ); // 创建一个圆形对象
Cylinder cylinder( 10, 3.3, 10, 10 ); // 创建一个圆柱体对象
point.PrintShapeName(); // 前期绑定
point.Print(); // 前期绑定
cout << '\n';
circle.PrintShapeName(); // 前期绑定
circle.Print(); // 前期绑定
cout << '\n';
cylinder.PrintShapeName(); // 前期绑定
cylinder.Print(); // 前期绑定
cout << "\n\n";
Shape *arrayOfShapes[3]; // 基类的数组
// arrayOfShapes[0]指向Point对象
arrayOfShapes[0] = &point;
// arrayOfShapes[1]指向Circle对象
arrayOfShapes[1] = &circle;
// arrayOfShapes[2]指向Cylinder对象
arrayOfShapes[2] = &cylinder;
// 利用动态绑定通过调用virtualViaPointer()函数来访问各个对象
cout << "Virtual function calls made of base-class pointers\n";
for ( int i = 0; i < 3; i++ )
virtualViaPointer( arrayOfShapes[i] );
// 利用动态绑定通过调用virtualViaReference()函数来访问各个对象
cout << "Virtual function calls made of base-class references\n";
for (int j = 0; j < 3; j++ )
virtualViaReference( *arrayOfShapes[j] );
return 0;
}
void virtualViaPointer( Shape *baseClassPtr )
{
baseClassPtr->PrintShapeName();
baseClassPtr->Print();
cout << "\nArea = "<< baseClassPtr->Area()
<< "\nVolume =" << baseClassPtr->Volume() << "\n\n";
}
void virtualViaReference( Shape &baseClassRef )
{
baseClassRef.PrintShapeName();
baseClassRef.Print();
cout << "\nArea = "<< baseClassRef.Area()
<< "\nVolume "<< baseClassRef.Volume() << "\n\n";
}
基类Shape由4个public虚函数组成,不包含任何数据。函数Print()和PrintShapeName()是纯虚函数,因此它们要在每个派生类中重新定义。函数Area()和Volume()都返回0,当派生类需要对面积(area)和(或)体积(volume)有不同的计算方法时,这些函数就需要在派生类中重新定义。注意Shape虽然是个抽象类,但可以包含一些“不纯”的虚函数(area和volume)。另外,抽象类也可以包含非虚函数和数据成员。
Point类是通过public继承从Shape类派生来的。因为Point没有面积和体积(均为0),所以类中没有重新定义基类成员函数Area()和Volume(),而是从类Shape中继承这两个函数。函数PrintShapeName()和Print()是对Shape类中对应的这两个纯虚函数的实现,如果不在Point类中重新定义这些基类中的纯虚函数,则Point仍然为抽象类、不能实例化Point对象。其他成员函数包括:将新的x和y坐标值赋绐Point对象(即点)的一个SetPoint()函数和返回Point对象的x和y坐标值的GetX()和GetY()函数。
Circle类是通过public继承从Point类派生来的。因为它没有体积,所以类中没有重新定义基类成员函数Volume(),而是从Point类中继承。Circle是有面积的,因此要重新定义函数Area()。函数printShapeName()和print()是对Point类中这两个函数的重新定义。如果此处不重新定义这两个函数,则会继承Point类中的函数实现。其他成员函数包括为Circle对象设置新的radius(半径值)的SetRadius()函数和返回Circle对象的m_radius的GetRadius()函数。
Cylinder类是通过public继承从Circle类派生来的。因为Cylinder对象的面积和体积同Circle的不同,所以需要在类中重新定义函数Area()和Volume()。函数PrintShapeName()和Print()是对Circle类中这两个函数的重新定义。如果此处不重新定义该函数,则会继承Circle类中的函数实现。Cylinder类中还包括一个设置Cylinder对象m_height(高度)的SetHeight()函数和一个读取Cylinder对象(圆柱体)m_height的GetHeight()函数。
主函数一开始就分别实例化了Point类的对象point、Circle类的对象circle和Cylinder类的对象cylinder。程序随后调用了每个对象的PrintShapeName()和Print()函数,并输出每一个对象的信息以验证对象初始化的正确性。每次通过对象名调用PrintShapeName()和Print()都使用前期绑定,编译器在编译时知道调用PrintShapeName()和Print()的每种对象类型。
接着把指针数组arrayOfShapes的每个元素声明为Shape*类型,该数组用来指向每个派生类对象。首先把对象point的地址赋给了arrayOfShapes[0]、把对象circle的地址赋给了arrayOfShapes[1]、把对象cylinder的地址赋给了arrayOfShapes[2]。
然后用for循环遍历arrayOfShapes数组,并对每个数组元素调用函数virtualViaPointer:
virtualViaPointer(arrayOfShapes[i]);
函数virtualViaPointer用baseClassPtr(类型为Shape*)参数接收arrayOfShapes数组中存放的地址。每次执行virtualViaPointer时,调用下列4个虚函数:
baseClassPtr->PrintShapeName()
baseClassPtr->Print()
baseClassPtr->Area()
baseClassPtr->Volume()
通过动态绑定,程序会根据baseClassPtr实际所指的对象类型调用该对象所属类的成员函数。首先,输出字符串“Point:”和相应的point对象,面积和体积的计算结果都是0.00。然后,输出字符串“Circle:”和circle对象的圆心及半径,程序计算出了对象circle的面积,返回体积值为0.00。最后,输出字符串“Cylinder:”以及相应的cylinder对象的底面圆心、半径和高,程序计算出了对象cylinder的面积和体积。
最后用for循环遍历arrayOfShapes数组,并对每个数组元素调用函数virtualViaReference():
virtualViaReference(*arrayofShapes[j]);
函数virtualViaReference()用baseClassRef(类型为Shape&)参数接收对arrayOfShapes数组元素指向的每个对象的引用。每次执行virtualViaReference()时,调用下列4个虚函数:
baseClassRef.PrintShapeName()
baseClassRef.Print()
baseClassRef.Area()
baseClassRef.Volume()
通过动态绑定,程序会根据baseClassRef实际所引用的对象类型调用该对象所属类的函数。这里使用基类引用作为函数参数的输出结果与前面使用基类指针作为函数参数时输出的结果相同。
【例3】下面的范例程序用虚函数和多态性根据雇员的类型完成工资单的计算。
类层次分析:
类层次中的基类是雇员类Employee,其派生类包括:老板类Boss,不管工作多长时间他总是有固定的周薪;销售员CommissionWorker,他的收入是一小部分基本工资加上销售额的一定的百分比;计件工类PieceworkWorker,他的收入取决他生产的工件数量;小时工类HourlyWorker,他的收入以小时计算,再加上加班费。
函数Earnings用于计算雇员的工资。每人收入的计算方法取决于它属于哪一类雇员,因此,它在基类Employee中被声明为virtual,并在每个派生类中都重新定义。为计算任何雇员的收入,程序简单地使用了一个指向该雇员对象的基类指针并调用Earnings函数。在一个实际的工资单系统中,各种雇员对象可能保存在一个指针数组(链表)中,数组中每个元素都是Employee *类型,通过每一个数组元素即可调用该元素所指向的雇员对象的Earnings函数。
Employee类的public成员函数包括:构造函数,该构造函数有两个参数,第一个参数是雇员的姓,第二个参数是雇员的名;析构函数,用来释放动态分配的内存;GetFirstName()和GetLastName()函数,分别返回雇员的姓和名;纯虚函数Earnings()和虚函数Print()。之所以要把Earnings函数声明为纯虚函数,是因为在Employee类中提供这个函数的实现是没有意义的,将它声明为纯虚函数表示要在派生类中而不是在基类中提供具体的实现。对于具有广泛含义的雇员,我们不能计算出他的收入,而必须首先知道该雇员的类型。程序员不会试图在基类Employee中调用该纯虚函数,所有派生类根据各自的计算方法重定义Earnings()。
Boss类是通过public继承从Employee类派生出来的,它的public成员函数包括:构造函数,构造函数有三个参数,即雇员的姓和名以及周薪,为了初始化派生类对象中基类部分的成员m_firstName和m_lastName,雇员的姓和名传递给了Employee类的构造函数;SetWeeklySalary()函数,用来把周薪值赋给private数据成员m_weeklySalary;虚函数Earnings(),用来定义如何计算Boss的工资;虚函数Print(),它输出雇员类型,然后调用Employee:Print()输出员工姓名。
CommissionWorker类是通过public继承从Employee类派生出来的,它的public成员函数包括:构造函数,构造函数有五个参数,即姓、名、基本工资、回扣及产品销售量,并将姓和名传递给了Employee类的构造函数;函数SetSalary()、SetCommission和SetQuantity(),用于给private数据成员m_salary、m_commission和m_quantity赋值;虚函数Earnings(),用来定义如何计算CommissionWorker的工资;虚函数Print(),输出雇员类型,然后调用Employs:Print()输出员工姓名。
PieceWorker类是通过public继承从Employee类派生出来的,public成员函数包括:构造函数,构造函数有四个参数,即计件工的姓、名、每件产品的工资以及生产的产品数量,并将姓和名传递给了类Employee的构造函数;函数SetWate()和SetQuantity(),用来给private数据成员m_wagePerPiece和m_quantity赋值;虚函数Earnings(),用来定义如何计算PieceWorker的工资;虚函数Print(),它输出雇员类型,然后调用Employee:Print()输出员工姓名。
HourlyWorker类是通过public继承从Employee类派生出来的,public成员函数包括: 构造函数,构造函数有四个参数,即姓、名、每小时工资及工作的时间数,并将姓、名传递给了类Employee的构造函数;函数SetHours(),用于给private数据成员m_wage和m_hours赋值;虚函数Earnings(),用来定义如何计算HourlyWorker的工资;虚函数Print(),输出雇员类型,然后调用Employee:Print()输出员工姓名。
//Employee.h
//抽象类Employee
#ifndef Employee_h // 条件编译,避免重复定义
#define Employee_h
class Employee
{
public:
Employee(const char *, const char *);
~Employee();
const char *GetFirstName();
const char *GetLastName();
virtual double Earnings()= 0; // 纯虚函数,Employee成为抽象类
virtual void Print(); // 虚函数
private:
char *m_firstName;
char *m_lastName;
};
#endif
//Employee.cpp
//抽象类Employee的成员函数定义
#include <string>
#include <iostream>
using namespace std;
#include "employee.h"
//构造函数,用姓和名来进行初始化
Employee::Employee(const char *first, const char *last)
{
m_firstName = new char [strlen(first) + 1 ];
strcpy(m_firstName, first);
m_lastName = new char [strlen(last) + 1 ];
strcpy(m_lastName, last);
}
// 析构函数,释放空间
Employee::~Employee()
{
delete [] m_firstName;
delete [] m_lastName;
}
//返回一个指向名的指针
//返回一个常量指针,防止调用者修改私有数据
const char *Employee::GetFirstName()
{
return m_firstName;
}
//返回一个指向姓的指针
//返回一个常量指针,防止调用者修改私有数据
const char *Employee::GetLastName()
{
return m_lastName;
}
// 输出Employee的姓名
void Employee::Print()
{
cout << m_firstName << ' ' << m_lastName;
}
//Boss.h
#include"Employee.h"
class Boss : public Employee //继承Employee类
{
public:
Boss(const char *, const char *, double = 0.0);
void SetWeeklySalary(double);
virtual double Earnings() ;
virtual void Print() ;
private:
double m_weeklySalary;
};
//Boss.cpp
//Boss类的成员函数定义
#include "Boss.h"
#include <iostream>
using namespace std;
// Boss类的构造函数
Boss::Boss(const char *first, const char *last, double s)
: Employee( first, last ) //调用基类的构造函数
{
SetWeeklySalary(s);
}
// 设置boss的薪水
void Boss::SetWeeklySalary(double s)
{
m_weeklySalary = s > 0 ? s : 0;
}
// 得到boss的报酬
double Boss::Earnings()
{
return m_weeklySalary;
}
// 打印boss的名字
void Boss::Print()
{
cout << "\n Boss: ";
Employee::Print();
}
// CommissionWorker.h
#include"employee.h"
class CommissionWorker : public Employee
{
public:
CommissionWorker(const char *, const char *,
double = 0.0, double = 0.0,int= 0);
void SetSalary(double);
void SetCommission(double);
void SetQuantity(int);
virtual double Earnings();
virtual void Print() ;
private:
double m_salary; // 每周的基本薪水
double m_commission; // 每卖一件货物的提成
int m_quantity; // 一周卖出的总货物量
};
//CommissionWorker.cpp
//CommissionWorker类成员函数的定义
#include "commissionWorker.h"
#include <iostream>
using namespace std;
CommissionWorker::CommissionWorker(const char * first,const char *last, double s, double c, int q) : Employee(first, last) // 调用基类构造函数
{
SetSalary(s);
SetCommission(c);
SetQuantity(q);
}
// 设置CommissionWorker的周基本薪水
void CommissionWorker::SetSalary(double s)
{
m_salary = s > 0 ? s : 0;
}
// 设置CommissionWorker的任务
void CommissionWorker::SetCommission(double c)
{
m_commission = c > 0 ? c : 0;
}
// 设置commissionWorker的销售数量
void CommissionWorker::SetQuantity(int q)
{
m_quantity = q > 0 ? q : 0;
}
// 计算CommissionWorker的报酬
double CommissionWorker::Earnings()
{
return m_salary + m_commission * m_quantity;
}
// 打印CommissionWorker的名字
void CommissionWorker::Print()
{
cout << "\nCommission worker: ";
Employee::Print();
}
//PieceWorker.h
#include"employee.h"
class PieceWorker : public Employee
{
public:
PieceWorker(const char *, const char *, double = 0.0, int = 0);
void SetWage(double);
void SetQuantity(int);
virtual double Earnings();
virtual void Print();
private:
double m_wagePerPiece; // 每件产品的报酬
int m_quantity; // 一周总产品数
};
//PieceWorker.cpp
#include <iostream>
using namespace std;
#include "pieceworker.h"
// PieceWorker的构造函数
PieceWorker::PieceWorker(const char *first, const char *last,double w, int q)
: Employee(first, last) //调用基类构造函数
{
SetWage(w);
SetQuantity(q);
}
// 设置报酬
void PieceWorker::SetWage(double w)
{
m_wagePerPiece = w > 0 ? w : 0;
}
// 设置产品数量
void PieceWorker::SetQuantity(int q)
{
m_quantity = q > 0 ? q : 0;
}
// 计算PieceWorker的报酬
double PieceWorker::Earnings()
{
return m_quantity * m_wagePerPiece;
}
// 打印PieceWorker的姓名
void PieceWorker::Print()
{
cout << "\n Piece worker: ";
Employee::Print();
}
//HourlyWorker.h
#include "Employee.h"
class HourlyWorker : public Employee
{
public:
HourlyWorker(const char *, const char *,double = 0.0, double = 0.0);
void SetWage(double);
void SetHours(double);
virtual double Earnings();
virtual void Print ();
private:
double m_wage; // 每小时薪水
double m_hours; // 每周总工作小时数
};
//HourlyWorker.cpp
#include "HourlyWorker.h"
#include <iostream>
using namespace std;
// Constructor for class HourlyWorker
HourlyWorker::HourlyWorker(const char *first, const char *last,double w, double h)
: Employee(first, last) // 调用基类构造函数
{
SetWage(w);
SetHours(h);
}
// 设置每小时报酬
void HourlyWorker::SetWage(double w)
{
m_wage = w > 0 ? w : 0;
}
// 设置工作总工作小时数
void HourlyWorker::SetHours(double h)
{
m_hours = h >= 0 && h < 168 ? h : 0;
}
// 计算HourlyWorker的报酬
double HourlyWorker::Earnings()
{
if (m_hours <= 40) // 没有加班
return m_wage * m_hours;
else // 加班时间薪水为wage * 1.5
return 40 * m_wage+(m_hours-40)*m_wage*1.5;
}
//打印HourlyWorker的姓名
void HourlyWorker::Print()
{
cout << "\n Hourly worker: ";
Employee::Print();
}
//test.cpp
#include <iomanip>
#include <iostream>
using namespace std;
#include "employee.h"
#include "boss.h"
#include "commissionworker.h"
#include "pieceworker.h"
#include "hourlyworker.h"
void virtualViaPointer(Employee *);
void virtualViaReference(Employee &);
// 用基类指针实现后期绑定
void virtualViaPointer(Employee *baseClassPtr)
{
baseClassPtr->Print();
cout << " earned $" << baseClassPtr->Earnings();
}
// 用基类对象引用实现后期绑定
void virtualViaReference(Employee &baseClassRef)
{
baseClassRef.Print();
cout << " earned $ " << baseClassRef.Earnings();
}
int main()
{
// 设置输出格式
cout << setiosflags(ios::fixed | ios::showpoint) << setprecision( 2 );
Boss b( "John", "Smith", 800.00 );
virtualViaPointer(&b); //后期绑定
virtualViaReference(b); //后期绑定
CommissionWorker c("Sue", "Jones", 200.0, 3.0, 150);
virtualViaPointer(&c);
virtualViaReference(c);
PieceWorker p("Bob", "Lewis", 2.5, 200);
virtualViaPointer(&p);
virtualViaReference(p);
HourlyWorker h("Karen", "Price", 18.75, 40);
virtualViaPointer(&h);
virtualViaReference(h);
cout << endl;
return 0;
}
-C++的常见错误
--C++的常见错误
-MFC入门
--MFC入门
-STL及使用示例
--STL及使用示例
-算法设计与算法分析基础
-算法设计基本方法与策略基础
-计算机前沿问题思考
-QT编程入门
--QT编程入门
-C++中的string类
-面向对象方法应用实例
-继承与多态应用实例
-排序算法
--排序算法
-C++常见问题汇总
-学习感悟(1)
--学习感悟(1)
-学习感悟(2)
--学习感悟(2)
-学习感悟(3)
--学习感悟(3)
-学习感悟(4)
--学习感悟(4)
-1.1面向对象方法的基本概念
-1.1面向对象方法的基本概念--作业
-1.2 C++中类的定义
-1.2 C++中类的定义
-1.3C++中对象的定义和访问
-1.3C++中对象的定义和访问--作业
-1.4类成员的访问控制
-1.4类成员的访问控制--作业
-1.5析构函数
--1.5析构函数
-1.5析构函数--作业
-1.6拷贝构造函数
-1.6拷贝构造函数--作业
-1.7 类声明与类实现的分离
-1.7 类声明与类实现的分离--作业
-1.8类的静态成员
-1.8类的静态成员--作业
-1.9类的常量成员
-1.9类的常量成员--作业
-1.10this指针
-1.10this指针--作业
-1.11类的友元
--1.11类的友元
-1.11类的友元--作业
-1.12类的对象成员
-1.12类的对象成员--作业
-1.13自定义类的运算符重载
-1.13自定义类的运算符重载--作业
-2.1 派生类的定义和继承方式
-2.1 派生类的定义和继承方式--作业
-2.2 派生类中函数的重定义
-2.2 派生类中函数的重定义--作业
-2.3派生类的构造函数和析构函数
-2.3派生类的构造函数和析构函数--作业
-2.4多继承
--2.4多继承
-2.4多继承--作业
-2.5多态
--2.5多态
-2.5多态--作业
-2.6抽象类
--2.6抽象类
-2.6抽象类--作业
-3.1cout和cin对象及插入和提取运算符
-3.1cout和cin对象及插入和提取运算符--作业
-3.2 使用put和get函数进行标准输出和输入
-3.3使用getline函数进行标准输入
-3.3使用getline函数进行标准输入--作业
-3.4 文件流对象
-3.5文件流对象及插入和提取运算符
-3.5文件流对象及插入和提取运算符--作业
-3.6文件流对象及put、get和getline函数
-3.7按数据块进行输入输出
-3.8按数据块进行输入输出实例
-3.8按数据块进行输入输出实例--作业
-3.9文件的随机读写
-3.9文件的随机读写--作业
-3.10用户自定义数据类型的输入输出
-3.10用户自定义数据类型的输入输出--作业
-4.1函数模板
--4.1函数模板
-4.1函数模板--作业
-4.2类模板
--4.2类模板
-4.2类模板--作业
-5.1数据结构基本概念(一)
-第五章 概论--5.1数据结构基本概念(一)
-5.2数据结构基本概念(二)
-5.2数据结构基本概念(二)--作业
-6.1线性表及其抽象数据类型
-6.1线性表及其抽象数据类型--作业
-6.2顺序表类模板
-6.2顺序表类模板--作业
-6.3顺序表的实现
-6.3顺序表的实现--作业
-6.4简单数据元素顺序表的应用问题
-6.4简单数据元素顺序表的应用问题--作业
-6.5复杂数据元素顺序表的应用问题
-6.5复杂数据元素顺序表的应用问题--作业
-6.6单向链表及其类模板
-6.6单向链表及其类模板--作业
-6.7单项链表的实现(一)
-6.7单项链表的实现(一)--作业
-6.8单项链表的实现(二)
-6.8单项链表的实现(二)--作业
-6.9单向链表的应用
-6.10循环链表及双向链表
-7.1栈及顺序栈
--7.1栈及顺序栈
-7.1栈及顺序栈--作业
-7.2 顺序栈的实现
-7.2 顺序栈的实现--作业
-7.3顺序栈的应用
-7.4 链接栈及其实现
-7.4 链接栈及其实现--作业
-7.5队列及其顺序存储
-7.5队列及其顺序存储--作业
-7.6 顺序循环队列的实现
-7.6 顺序循环队列的实现--作业
-7.7顺序循环队列的应用
-7.8链接队列及其实现
-7.8链接队列及其实现--作业
-8.1树的基本概念
-8.1树的基本概念--作业
-8.2二叉树及其性质
-8.2二叉树及其性质--作业
-8.3二叉树的抽象数据类型和顺序表示
-8.3二叉树的抽象数据类型和顺序表示--作业
-8.4二叉树的链式表示
-第八章 树和二叉树--8.4二叉树的链式表示
-8.5二叉链表的实现(一)
-8.6二叉链表的实现(二)先序和中序遍历
-8.6二叉链表的实现(二)先序和中序遍历--作业
-8.7二叉链表的实现(三)后序和逐层遍历
-8.7二叉链表的实现(三)后序和逐层遍历--作业
-8.8二叉链表的实现(四)
-8.9 二叉排序树
-8.10哈夫曼树和哈夫曼编码
-9.1图的基本概念及其特征
-9.1图的基本概念及其特征--作业
-9.2图的抽象数据类型和表示方式
--Video
-9.2图的抽象数据类型和表示方式--作业
-9.3图的邻接矩阵表示法的实现
-9.3图的邻接矩阵表示法的实现--作业
-9.4图的广度优先遍历
--Video
-9.4图的广度优先遍历--作业
-9.5图的深度优先遍历
-9.5图的深度优先遍历--作业
-9.6图的应用
--9.6 图的应用
-面向对象方法
--面向对象例题讲解
--友元和运算符重载
--对象成员
-继承与多态
--多重继承
--虚函数
--抽象类和纯虚函数
-输入输出流
--输入输出流操作
-模板
--函数模板
--类模板