纯虚函数
在基类中不能给出有意义的虚函数
定义,这时可以把它声明成纯虚函数
,把它的定义留给派生类来做。纯虚函数不需要实现。
定义纯虚函数
class 类名{
virtual 返回值类型 函数名(参数表) = 0;
};
抽象类
抽象类只能作为基类来使用。不能声明抽象类的对象。构造函数不能是虚函数,析构函数可以是虚函数。构造函数不能为虚函数
,因为对象没有构造,无法形成虚函数表,即无法运行时多态。
若构造函数中存在虚函数,虚函数在构造函数中,已经失去了虚函数的动态绑定特性
- 抽象类不能用于直接创建对象实例,可以声明抽象类的指针和引用
- 可使用
指向抽象类的指针支持运行时多态性
派生类中必须实现基类中的纯虚函数,否则它仍将被看作一个抽象类
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Shape
{
public:
virtual void Draw() = 0;
virtual ~Shape()
{
cout << "~Shape..." << endl;
}
};
class Circle : public Shape
{
public:
void Draw()
{
cout << "Circle::Draw() ..." << endl;
}
~Circle()
{
cout << "~Circle ..." << endl;
}
};
class Square : public Shape
{
public:
void Draw()
{
cout << "Square::Draw() ..." << endl;
}
~Square()
{
cout << "~Square ..." << endl;
}
};
class Rectangle : public Shape
{
public:
void Draw()
{
cout << "Rectangle::Draw() ..." << endl;
}
~Rectangle()
{
cout << "~Rectangle ..." << endl;
}
};
void DrawAllShapes(const vector<Shape *> &v)
{
vector<Shape *>::const_iterator it;
for (it = v.begin(); it != v.end(); ++it)
{
(*it)->Draw();
}
}
void DeleteAllShapes(const vector<Shape *> &v)
{
vector<Shape *>::const_iterator it;
for (it = v.begin(); it != v.end(); ++it)
{
delete(*it);
}
}
// 简单工厂模式
class ShapeFactory
{
public:
static Shape *CreateShape(const string &name)
{
Shape *ps = 0;
if (name == "Circle")
{
ps = new Circle;
}
else if (name == "Square")
{
ps = new Square;
}
else if (name == "Rectangle")
{
ps = new Rectangle;
}
return ps;
}
};
int main(void)
{
//Shape s; //Error,不能实例化抽象类
vector<Shape *> v;
//Shape* ps;
//ps = new Circle;
//v.push_back(ps);
//ps = new Square;
//v.push_back(ps);
//ps = new Rectangle;
//v.push_back(ps);
Shape *ps;
ps = ShapeFactory::CreateShape("Circle");
v.push_back(ps);
ps = ShapeFactory::CreateShape("Square");
v.push_back(ps);
ps = ShapeFactory::CreateShape("Rectangle");
v.push_back(ps);
DrawAllShapes(v);
DeleteAllShapes(v);
return 0;
}
程序结果输出
Circle::Draw() ...
Square::Draw() ...
Rectangle::Draw() ...
~Circle ...
~Shape...
~Square ...
~Shape...
~Rectangle ...
~Shape...
虚析构函数
析构函数可以声明为虚函数,析构函数还可以是纯虚的
。
- delete基类指针,程序会根据基类指针指向的对象的类型确定要调用的析构函数
- 基类的析构函数为虚函数,
所有派生类的析构函数都是虚函数
#include <iostream>
using namespace std;
// 对于一个没有任何接口的类,如果想要将它定义成抽象类,只能将虚析构函数声明为纯虚的
// 通常情况下在基类中纯虚函数不需要实现
// 例外是纯虚析构函数要给出实现。(给出一个空的实现即可)
class Base
{
public:
virtual ~Base() = 0
{
}
};
class Derived : public Base
{
};
int main(void)
{
// Base b; //error, 抽象类
Derived d;
return 0;
}
通常情况下在基类中纯虚函数不需要实现,例外是纯虚析构函数要给出实现,给出一个空的实现即可。