#include<iostream>
using namespace std;
//C++的多态与虚函数
//基类Point
class Point {
public:
Point(int xa, int yb) { //有参构造函数
x = xa;
y = yb;
}A
Point(){
x = 0;
y = 0;
}
//定义虚函数display(),满足子类继承时的多态效应。
//补全代码
//----------------------------------------------------
//由于在Point基类阶段,无法实现实际的求面积方法,因此将get_area()设计为纯虚函数。
//请补全代码
//------------------------------------------------
//析构函数通常定义为虚函数
//请补全析构函数头
//--------------------------------
{
cout << "Point destructor" << endl;
}
protected:
int x; //x坐标
int y; //y坐标
};
//Square继承了Point
class Square : public Point{
public:
Square(int xa, int xb, int len):Point(xa,xb),length(len){
}
Square()
{
length = 1;
}
void display(){
//显示一个方形
cout<<"调用Square的display函数,显示一个正方形.\n"<< "坐标:(" << x << ", " << y << "), 边长:" << length <<endl;
}
//补全代码,实现自己的求面积函数get_area
//--------------------------------------
//析构函数通常定义为虚函数
//请补全析构函数头
//--------------------------------------
{
cout << "Square destructor" << endl;
}
protected:
int length;
};
//Circle继承了Point
class Circle: public Point {
public:
Circle(int xa, int xb, int r):Point(xa,xb) {
radius = r;
}
Circle(){
radius = 1;
}
void display() { //显示一个圆
cout<<"调用Circle的display函数,显示一个圆.\n"<< "坐标:(" << x << ", " << y << "), 半径:" << radius <<endl;
}
//补全代码,实现自己的求面积函数get_area
//------------------------------------------
//析构函数通常定义为虚函数
//请补全析构函数头
//-----------------------------------------------
{
cout << "Circle destructor" << endl;
}
protected:
int radius;
};
//编写一个Triangle类,继承Point,属性包含底边长和高
//并有自己的有参,无参构造函数,display函数和get_area函数,以及析构函数
//此处补全代码:
//---------------------------------------------------------------
//显示一个图形的通用函数Disp
void Disp(/*补全代码,填上参数,仔细思考这里应该填写什么类型的 对象?引用?指针?*/)
{
p.display();
}
//显示一个图形面积的通用函数:Area_of_shape
void Area_of_shape(/*补全代码,填上参数,仔细思考这里应该填写什么类型的 对象?引用?指针?*/)
{
cout << s->get_area() << endl;
}
//函数create_shapes实现在堆内存中,动态生成一组图形,并返回首地址。
//option表示图形类型,1为方形,2为圆形,3为三角形
//num为生成图形的数量
Point* create_shapes(int option, int num)
{
//补全代码,实现功能
//建议使用switch,并注意new对象数组的用法。
//--------------------------------------------
}
int main() {
//在堆内存中生成不同的图形。
//定义基类图形指针
Point *p;
int num;//个数
//输入即将生成的方形个数
cin >> num;
//生成一组方形
p = create_shapes(1, num);
//依次显示这组方形的基本信息,以及面积。
for(int i = 0; i < num; i++)
{
//注意:p作为基类指针,在指向子类数组时,
//其对于属性的作用范围仍局限在子类中的基类属性。
//若直接通过+i或[i]形式,会造成内存指向的错位。
//因此,需要想办法将其强制转换为子类类型的指针。
//下同
//显示基本信息
Disp(/*补全代码,填写实参*/);
//显示面积值
Area_of_shape(/*补全代码,填写实参*/);
}
//注销
//注意,由于涉及到数组的注销,因此注销时,基类指针,也需要转换为子类指针才能顺利注销,下同。
//请补齐注销代码
//--------------------------------
//输入即将生成的圆形个数
cin >> num;
//生成一组圆形
p = create_shapes(2, num);
//依次显示这组圆形的基本信息,以及面积。
for(int i = 0; i < num; i++)
{
Disp(/*补全代码,填写实参*/);
Area_of_shape(/*补全代码,填写实参*/);
}
//注销
//请补齐注销代码
//--------------------------------
//输入即将生成的三角形个数
cin >> num;
//生成一组三角形
p = create_shapes(3, num);
//依次显示这组三角形的基本信息,以及面积。
for(int i = 0; i < num; i++)
{
Disp(/*补全代码,填写实参*/);
Area_of_shape(/*补全代码,填写实参*/);
}
//注销
//请补齐注销代码
//----------------------------------------------------
return 0;
}
基于new bing的编写参考:
定义虚函数display和纯虚函数get_area,具体内容由子类去实现。
class Point {
public:
Point(int xa, int yb) { // 有参构造函数
x = xa;
y = yb;
}
Point() {
x = 0;
y = 0;
}
virtual void display() {
cout << "调用Point的display函数,显示一个点。" << endl;
}
virtual double get_area() = 0; // 纯虚函数,由子类去实现
virtual ~Point() {
cout << "Point destructor" << endl;
}
protected:
int x; // x坐标
int y; // y坐标
};
在Square和Circle类中分别实现display和get_area函数,并在析构函数中输出提示信息。
class Square : public Point {
public:
Square(int xa, int xb, int len):Point(xa, xb), length(len) {}
Square() {
length = 1;
}
void display() {
cout << "调用Square的display函数,显示一个正方形。" << endl;
cout << "坐标:(" << x << ", " << y << "), 边长:" << length << endl;
}
double get_area() {
return length * length;
}
~Square() {
cout << "Square destructor" << endl;
}
private:
int length;
};
class Circle: public Point {
public:
Circle(int xa, int xb, int r):Point(xa, xb), radius(r) {}
Circle() {
radius = 1;
}
void display() {
cout << "调用Circle的display函数,显示一个圆。" << endl;
cout << "坐标:(" << x << ", " << y << "), 半径:" << radius << endl;
}
double get_area() {
return 3.14 * radius * radius;
}
~Circle() {
cout << "Circle destructor" << endl;
}
private:
int radius;
};
添加Triangle类,与Square和Circle类类似,实现display和get_area函数,并在析构函数中输出提示信息。
class Triangle : public Point {
public:
Triangle(int xa, int xb, int base, int height):Point(xa, xb), base(base), height(height){}
Triangle(){
base = 1;
height = 1;
}
void display(){
cout << "调用Triangle的display函数,显示一个三角形。" << endl;
cout << "坐标:(" << x << ", " << y << "), 底边长:" << base << ", 高:" << height << endl;
}
double get_area(){
return 0.5 * base * height;
}
~Triangle(){
cout << "Triangle destructor" << endl;
}
private:
int base; // 底边长
int height; // 高
};
在create_shapes函数中使用switch语句和new对象数组来动态生成一组图形,并返回指向该数组的首地址的基类指针。
Point* create_shapes(int option, int num) {
switch (option) {
case 1: {
Square* squares = new Square[num];
return squares;
break;
}
case 2: {
Circle* circles = new Circle[num];
return circles;
break;
}
case 3: {
Triangle* triangles = new Triangle[num];
return triangles;
break;
}
default:
return nullptr;
break;
}
}
在main函数中,先生成一组方形并依次显示其属性和面积,然后注销该组方形,再生成一组圆形和一组三角形进行同样的操作。
int main() {
// 在堆内存中生成不同的图形。
// 定义基类图形指针
Point *p;
int num; // 个数
// 生成一组方形
cout << "请输入即将生成的方形个数:";
cin >> num;
p = create_shapes(1, num);
for(int i = 0; i < num; i++) {
Square* sq = dynamic_cast<Square*>(p + i);
if (sq) {
sq->display();
cout << "面积:" << sq->get_area() << endl;
}
}
delete[] p;
cout << endl;
// 生成一组圆形
cout << "请输入即将生成的圆形个数:";
cin >> num;
p = create_shapes(2, num);
for(int i = 0; i < num; i++) {
Circle* c = dynamic_cast<Circle*>(p + i);
if (c) {
c->display();
cout << "面积:" << c->get_area() << endl;
}
}
delete[] p;
cout << endl;
// 生成一组三角形
cout << "请输入即将生成的三角形个数:";
cin >> num;
p = create_shapes(3, num);
for(int i = 0; i < num; i++) {
Triangle* t = dynamic_cast<Triangle*>(p + i);
if (t) {
t->display();
cout << "面积:" << t->get_area() << endl;
}
}
delete[] p;
return 0;
}
虚函数用于实现多态
但是虚函数在设计上还具有封装和抽象的作用。比如抽象工厂模式。
多态和虚函数是C++中重要的特性之一,可以大大提高代码的可维护性和拓展性。如果你已经掌握了基本的C++语法,那么接下来可以开始学习多态和虚函数。
多态指的是同一个类的不同实例或者不同类之间的同名函数,可以根据调用的对象自动判断应该调用哪个函数,从而大大简化了代码的重用和扩展。
虚函数是实现多态的关键,可以通过定义一个基类,并让基类的某个成员函数为虚函数,从而让派生类对这个函数进行重写,实现多态特性。具体步骤如下:
首先我们需要定义一个基类,其中包含一个虚函数:
class Figure {
public:
virtual float area() = 0;
};
然后我们定义一个派生类Rectangle,并重写虚函数area:
class Rectangle : public Figure {
public:
float area() {
cout << "Rectangle area" << endl;
return 10.0;
}
};
同理,我们还可以定义其它的派生类,例如Circle:
class Circle : public Figure {
public:
float area() {
cout << "Circle area" << endl;
return 3.14;
}
};
在主函数中,我们可以定义Figure指针,并根据需要指向Rectangle或者Circle实例,然后调用虚函数area,实现多态特性:
int main() {
Figure* ptr;
Rectangle rec;
Circle cir;
ptr = &rec;
ptr->area();
ptr = ○
ptr->area();
return 0;
}
最后输出结果如下:
Rectangle area
Circle area
可以看到,当Figure指针ptr分别指向Rectangle和Circle时,调用的是不同的函数,实现了多态特性。
总结一下,实现多态和虚函数需要以下几个步骤:
如果你对多态和虚函数还有疑问,可以多看看相关的教程和例子,不断练习和测试。