一、概念
抽象类只表达一个概念,并不与具体的对象联系,通常为它的派生类提供一个算法框架。需要注意的是,抽象类不光没有对象,也不能声明此类型,即抽象类型不能作为参数和返回值类型等。纯虚函数是一种特殊的虚函数,这种函数名称定义只有声明。 纯虚函数的语法格式如下:
virtual 返回值类型 函数名(参数列表) = 0;
抽象类 ←→ 纯虚函数
如果一个类是抽象类,则内部必然有纯虚函数;如果一个类有纯虚函数,其必然是抽象类。
#include <iostream>
using namespace std;
/**
* @brief The Shape class
* 抽象基类:形状类
*/
class Shape
{
public:
// 纯虚函数声明
virtual void area() = 0; // 面积
virtual void perimeter() = 0; // 周长
};
int main()
{
// Shape s; 错误
return 0;
}
二、用法
用法一:派生类继承抽象基类,把所有的纯虚函数覆盖并增加函数体。
#include <iostream>
using namespace std;
/**
* @brief The Shape class
* 抽象基类:形状类
*/
class Shape
{
public:
// 纯虚函数声明
virtual void area() = 0; // 面积
virtual void perimeter() = 0; // 周长
};
/**
* @brief The Circle class
* 圆形
*/
class Circle:public Shape
{
public:
void area()
{
cout << "πR^2" << endl;
}
void perimeter() override
{
cout << "2πR" << endl;
}
};
int main()
{
// Shape s; 错误
Circle c;
c.area();
c.perimeter();
return 0;
}
用法二:派生类继承抽象基类后,没有把所有的纯虚函数覆盖并增加函数体,此时相当于继承了纯虚函数,此派生类也变为抽象类。
#include <iostream>
using namespace std;
/**
* @brief The Shape class
* 抽象基类:形状类
*/
class Shape
{
public:
// 纯虚函数声明
virtual void area() = 0; // 面积
virtual void perimeter() = 0; // 周长
};
/**
* @brief The Circle class
* 圆形
*/
class Circle:public Shape
{
public:
void area()
{
cout << "πR^2" << endl;
}
void perimeter() override
{
cout << "2πR" << endl;
}
};
/**
* @brief The Polygon class
* 多边形
*/
class Polygon:public Shape
{
public:
void perimeter()
{
cout << "∑边长" << endl;
}
};
/**
* @brief The Triangle class
* 三角形
*/
class Triangle:public Polygon
{
public:
void area()
{
cout << "w*h/2" << endl;
}
};
int main()
{
// Shape s; 错误
Circle c;
c.area();
c.perimeter();
// Polygon p; 错误
Triangle t;
t.perimeter();
t.area();
return 0;
}
三、多态
之前提到抽象类型不能被声明,但是由于抽象类支持多态,因此抽象类的指针和引用可以被声明。同时要注意因为支持多态,抽象类的析构函数都应该被设置为虚析构函数。
#include <iostream>
using namespace std;
/**
* @brief The Shape class
* 抽象基类:形状类
*/
class Shape
{
public:
// 纯虚函数声明
virtual void area() = 0; // 面积
virtual void perimeter() = 0; // 周长
// 虚析构函数
virtual ~Shape()
{
}
};
/**
* @brief The Circle class
* 圆形
*/
class Circle:public Shape
{
public:
void area()
{
cout << "πR^2" << endl;
}
void perimeter() override
{
cout << "2πR" << endl;
}
};
/**
* @brief The Polygon class
* 多边形
*/
class Polygon:public Shape
{
public:
void perimeter()
{
cout << "∑边长" << endl;
}
};
/**
* @brief The Triangle class
* 三角形
*/
class Triangle:public Polygon
{
public:
void area()
{
cout << "w*h/2" << endl;
}
};
void test_shape(Shape& s)
{
s.area();
s.perimeter();
}
void test_shape(Shape *s)
{
s->area();
s->perimeter();
}
int main()
{
// Shape s; 错误
Circle c;
c.area();
c.perimeter();
// Polygon p; 错误
Triangle t;
t.perimeter();
t.area();
test_shape(c);
test_shape(t);
Circle* c2 = new Circle;
Triangle* t2 = new Triangle;
test_shape(c2);
test_shape(t2);
delete c2;
delete t2;
return 0;
}