Problem I: 不同交通工具的速度
Description
不同交通工具的速度是不同的。针对自行车、摩托车和汽车分别建立类,来模拟这一情况。
定义Vechicle类,是所有交通工具的父类:
属性int speed表示交通工具的一般速度。
静态数据成员int numOfVechicles,表示创建的交通工具的数量。这个值只增不减。
静态成员函数int getNumOfVechicles(),用于获取交通工具的数量。
析构函数。输出“A vechicle is deleted.”
纯虚函数void show().
定义Bike、MotoBike和Car三个类,它们都是Vechicle的子类,且具有:
构造函数。
重写show()函数,输出“A ’s speed is ? km/h.”,其中“”是bike、motobike或car,根据所在类不同而不同。“?”是speed属性的值。
析构函数。输出“A * is deleted.”,“*”的含义同上。
定义Person类,表示司机:
数据成员string name,是人的姓名。
void drive(Vechicle&)方法,输出“ drives”,并调用Vechicle类的show()方法。其中“ ”是name的值。
Input
第1行N>0,表示有N个测试用例。
每个测试用例包括一个不含空白符的字符串、一个字符和一个整数。
Output
见样例及题目描述。
Sample Input
3
Tom B 15
Jack M 50
Mary C 100
Sample Output
In beginning, we have 0 vechicles.
Tom drives. A bike’s speed is 15km/h.
A bike is deleted.
A vechicle is deleted.
Jack drives. A motobike’s speed is 50km/h.
A motobike is deleted.
A vechicle is deleted.
Mary drives. A car’s speed is 100km/h.
A car is deleted.
A vechicle is deleted.
At the end, we have 3 vechicles.
#include <iostream>
using namespace std;
class Vechicle
{
protected:
int speed;
static int numOfVechicles;
public:
Vechicle(int a=0):speed(a)
{
numOfVechicles++;
}
static int getNumOfVechicles()
{
return numOfVechicles;
}
virtual ~Vechicle()//
{
cout<<"A vechicle is deleted."<<endl;
}
virtual void show()=0;//纯虚函数
};
class Bike:public Vechicle
{
public:
Bike(int a1):Vechicle(a1){}
void show()
{
cout<<"A bike's speed is "<<speed<<"km/h."<<endl;
}
~Bike()
{
cout << "A bike is deleted."<<endl;
}
};
class Car:public Vechicle
{
public:
Car(int a1):Vechicle(a1){}
void show()
{
cout<<"A car's speed is "<<speed<<"km/h."<<endl;
}
~Car()
{
cout << "A car is deleted."<<endl;
}
};
class MotoBike:public Vechicle
{
public:
MotoBike(int a1):Vechicle(a1){}
void show()
{
cout<<"A motobike's speed is "<<speed<<"km/h."<<endl;
}
~MotoBike()
{
cout << "A motobike is deleted."<<endl;
}
};
class Person
{
private:
string name;
public:
Person(string Name):name(Name){}
void drive(Vechicle &p)
{
cout<<name<<" drives. ";
p.show();
}
};
int Vechicle::numOfVechicles=0;
int main()
{
int cases, n;
char c;
string name;
Vechicle* vechicle;
cout<<"In beginning, we have "<<Vechicle::getNumOfVechicles()<<" vechicles."<<endl;
cin>>cases;
for (int i = 0; i < cases; i++)
{
cin>>name>>c>>n;
Person person(name);
switch (c)
{
case 'B':
vechicle = new Bike(n);
break;
case 'M':
vechicle = new MotoBike(n);
break;
case 'C':
vechicle = new Car(n);
break;
}
person.drive(*vechicle);
delete vechicle;
}
cout<<"At the end, we have "<<Vechicle::getNumOfVechicles()<<" vechicles."<<endl;
return 0;
}
- 纯虚函数介绍:
为什么要用纯虚函数?
在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。为了解决这个问题,方便使用类的多态性,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;),则编译器要求在派生类中必须予以重写以实现多态性。同时含有纯虚拟函数的类称为抽象类,它不能生成对象。
在什么情况下使用纯虚函数(pure vitrual function)?
1,当想在基类中抽象出一个方法,且该基类只做能被继承,而不能被实例化;
2,这个方法必须在派生类(derived class)中被实现;
这里写链接内容
2.析构函数,构造函数中调用虚函数:
1.构造函数跟虚构函数里面都可以调用虚函数,编译器不会报错。
2.C++ primer中说到最好别用
3.由于类的构造次序是由基类到派生类,所以在构造函数中调用虚函数,虚函数是不会呈现出多态的
4.类的析构是从派生类到基类,当调用继承层次中某一层次的类的析构函数时意味着其派生类部分已经析构掉,所以也不会呈现多态
5.因此如果在基类中声明的纯虚函数并且在基类的析构函数中调用之,编译器会发生错误。
提示:
这里写链接内容