C++实现交通工具类层次结构:详尽指南
大家喜欢哪种方式,直接上代码还是这种详解?评论区留下你宝贵的建议
引言
在面向对象编程中,类之间的层次结构和继承关系是构建复杂系统的基石。本文将通过实现一个交通工具类层次结构的例子,来演示如何在C++中定义基类和派生类,并消除编译时产生的警告。我们将创建一个基类vehicle
,以及三个派生类car
、truck
和boat
,并定义虚函数来显示各类信息。
第一部分:定义基类和派生类
1. 定义基类vehicle
首先,我们需要定义一个名为vehicle
的基类,包含以下成员变量:速度(speed)、轮子数(wheels)和重量(weight)。同时,为了让派生类能够重写基类的函数,我们需要定义一个名为show
的虚函数。
class vehicle {
protected:
double speed; //速度,公里/小时
int wheels; //轮子数
double weight; //重量
public:
vehicle(double speed = 80, int wheels = 4, double weight = 1000);
virtual void show(void) = 0;
};
2. 定义派生类car
、truck
和boat
接下来,我们需要分别定义三个从基类vehicle
派生的类:car
、truck
和boat
。每个派生类都有自己的成员变量,并通过调用基类的构造函数来初始化基类成员。这里,我们为每个派生类定义了默认的构造函数,并将基类成员初始化为默认值。
class car : public vehicle {
int passenger_load;
public:
car(double speed = 80, int wheels = 4, double weight = 1000, int passenger_load = 4);
virtual void show(void);
};
class truck : public vehicle {
double rated_load; //额定载重
public:
truck(double speed = 80, int wheels = 4, double weight = 2500, double rated_load = 3000);
virtual void show(void);
};
class boat : public vehicle {
char kind; //轮船类别,如客轮为'k'
public:
boat(double speed = 30, int wheels = 0, double weight = 12000, char kind = 'k');
virtual void show(void);
};
第二部分:实现构造函数和虚函数
1. 实现基类构造函数
在基类vehicle
中,我们需要实现一个构造函数来初始化成员变量。这里,我们使用了C++的成员初始化列表语法,以提高代码的效率和简洁性。
vehicle::vehicle(double speed, int wheels, double weight)
: speed(speed), wheels(wheels), weight(weight) {}
2. 实现派生类构造函数和虚函数
对于每个派生类,我们需要实现它们自己的构造函数,以及重写基类的虚函数show
。这些虚函数在派生类中分别显示各类信息,如速度、轮子数、重量等。同时,我们还需要实现派生类的构造函数,并使用成员初始化列表来调用基类的构造函数。
car::car(double speed, int wheels, double weight, int passenger_load)
: vehicle(speed, wheels, weight), passenger_load(passenger_load) {}
void car::show(void) {
cout << "Car message\n";
cout << speed << " " << wheels << " " << weight << " " << passenger_load << endl;
}
truck::truck(double speed, int wheels, double weight, double rated_load)
: vehicle(speed, wheels, weight), rated_load(rated_load) {}
void truck::show(void) {
cout << "Truck message\n";
cout << speed << " " << wheels << " " << weight << " " << rated_load << endl;
}
boat::boat(double speed, int wheels, double weight, char kind)
: vehicle(speed, wheels, weight), kind(kind) {}
void boat::show(void) {
cout << "Boat message\n";
cout << speed << " " << wheels << " " << weight << " " << kind << endl;
}
第三部分:消除编译警告
1. 原始代码中的警告:
在编译原始代码时,我们遇到了以下警告信息:
main.cpp: In function 'int main()':
main.cpp:57:11: warning: deleting object of abstract class type 'vehicle' which has non-virtual destructor will cause undefined behaviour [-Wdelete-non-virtual-dtor]
delete unicycle;
^
main.cpp:59:11: warning: deleting object of abstract class type 'vehicle' which has non-virtual destructor will cause undefined behaviour [-Wdelete-non-virtual-dtor]
delete unicycle;
^
main.cpp:61:11: warning: deleting object of abstract class type 'vehicle' which has non-virtual destructor will cause undefined behaviour [-Wdelete-non-virtual-dtor]
delete unicycle;
^
2. 解决方法:添加虚析构函数
要解决这个警告,我们需要在基类vehicle
中添加一个虚析构函数。这样,在删除派生类对象时,基类的析构函数也会被调用,从而避免未定义的行为。
class vehicle {
// ...
virtual ~vehicle() {} // 添加虚析构函数
};
现在,代码将能够在没有警告的情况下成功编译。
第四部分:完整示例代码
将以上修改整合到一起,我们得到了一个消除了编译警告的完整示例代码
#include <iostream>
using namespace std;
class vehicle {
protected:
double speed; //速度,公里/小时
int wheels; //轮子数
double weight; //重量
public:
vehicle(double speed = 80, int wheels = 4, double weight = 1000);
virtual void show(void) = 0;
virtual ~vehicle() {} // 添加虚析构函数
};
vehicle::vehicle(double speed, int wheels, double weight)
: speed(speed), wheels(wheels), weight(weight) {}
class car : public vehicle {
int passenger_load;
public:
car(double speed = 80, int wheels = 4, double weight = 1000, int passenger_load = 4);
virtual void show(void);
};
car::car(double speed, int wheels, double weight, int passenger_load)
: vehicle(speed, wheels, weight), passenger_load(passenger_load) {}
void car::show(void) {
cout << "Car message\n";
cout << speed << " " << wheels << " " << weight << " " << passenger_load << endl;
}
class truck : public vehicle {
double rated_load; //额定载重
public:
truck(double speed = 80, int wheels = 4, double weight = 2500, double rated_load = 3000);
virtual void show(void);
};
truck::truck(double speed, int wheels, double weight, double rated_load)
: vehicle(speed, wheels, weight), rated_load(rated_load) {}
void truck::show(void) {
cout << "Truck message\n";
cout << speed << " " << wheels << " " << weight << " " << rated_load << endl;
}
class boat : public vehicle {
char kind; //轮船类别,如客轮为'k'
public:
boat(double speed = 30, int wheels = 0, double weight = 12000, char kind = 'k');
virtual void show(void);
};
boat::boat(double speed, int wheels, double weight, char kind)
: vehicle(speed, wheels, weight), kind(kind) {}
void boat::show(void) {
cout << "Boat message\n";
cout << speed << " " << wheels << " " << weight << " " << kind << endl;
}
int main() {
vehicle *unicycle;
car *BMW;
unicycle = new car;
unicycle->show();
BMW = (car *)unicycle;
BMW->show();
delete unicycle;
unicycle = new truck;
unicycle->show();
delete unicycle;
unicycle = new boat;
unicycle->show();
delete unicycle;
return 0;
}
结论:
通过这个例子,我们学习了如何在C++中定义基类和派生类、实现构造函数和虚函数,以及如何消除编译警告。这个简单的交通工具类层次结构示例展示了面向对象编程的强大功能,有助于我们更好地理解和应用C++的面向对象特性。
在实际项目中,我们可能会遇到更加复杂的类层次结构和继承关系。为了确保代码的可读性、可维护性和健壮性,我们需要:
- 合理地划分类层次结构,确保类之间的职责划分清晰。
- 尽量避免多重继承,以降低代码的复杂度。
- 充分利用虚函数和多态性,实现灵活的代码设计。
- 注意内存管理,避免内存泄漏和未定义行为。