纯虚函数和抽象类
大约 4 分钟
纯虚函数和抽象类
纯虚函数
纯虚函数是一种特殊的虚函数,。这就是纯虚函数的作用。纯虚函数的格式如下:
class 类名
{
public:
virtual 返回类型 函数名(参数包) = 0;
};
设置纯虚函数的意义,就是让所有的类对象(主要是派生类对象)都可以执行纯虚函数的动作,但类无法为纯虚函数提供一个合理的缺省实现。所以类纯虚函数的声明就是在告诉子类的设计者,“你提供一个纯虚函数的实现,但我不知道你会怎样实现它”。
class Base
{
public:
virtual void display() = 0;
};
class Derived
: public Base
{
public:
virtual void display()
{
cout << "Derived::display()" << endl;
}
};
声明纯虚函数的目的在于,提供一个与派生类。
class Figure
{
public:
virtual void display() const = 0;
virtual double area() const = 0;
};
class Circle
: public Figure
{
public:
explicit Circle(double radius)
: _radius(radius)
{
}
void display() const
{
cout << "Circle";
}
double area() const
{
return 3.14159 * _radius * _radius;
}
private:
double _radius;
};
class Rectangle
: public Figure
{
public:
Rectangle(double length, double width)
: _length(length)
, _width(width)
{
}
void display() const
{
cout << "Rectangle";
}
double area() const
{
return _length * _width;
}
private:
double _length;
double _width;
};
class Triangle
: public Figure
{
public:
Triangle(double a, double b, double c)
: _a(a)
, _b(b)
, _c(c)
{
}
void display() const
{
cout << "Triangle";
}
//海伦公式计算三角形的面积
double area() const
{
double p = (_a + _b + _c) / 2;
return sqrt(p * (p - _a) * (p - _b) * (p - _c));
}
private:
double _a;
double _b;
double _c;
};
抽象类
抽象类的形式
- 类中包含纯虚函数
一个类可以包含纯虚函数。只要类中含有一个纯虚函数,该类便为抽象类。。
//汽车的基类,抽象类
class Car
{
public:
Car(string name, double oil):_name(name),_oil(oil){}
//获取汽车剩余油量还能跑的公里数
double getLeftMiles()
{
//不同汽车1L油跑的公里不一样
return _oil * this->getMilesPerGallon();//动态绑定,
//基类指针指向不同派生类对象访问不同派生类重写的getMilesPerGallon()
}
string getName()const
{
return _name;
}
protected:
string _name;
double _oil;
virtual double getMilesPerGallon() = 0;//纯虚函数,根据具体的汽车而定1L油跑的公里数
};
class Bnze : public Car
{
public:
Bnze(string name, double oil):Car(name, oil){}
double getMilesPerGallon()
{
return 20.0;//具体的车跑到公里不一样
}
};
class Audi : public Car
{
public:
Audi(string name, double oil):Car(name, oil){}
double getMilesPerGallon()
{
return 18.0;//具体的车跑到公里不一样
}
};
class BMW : public Car
{
public:
BMW(string name, double oil):Car(name, oil){}
double getMilesPerGallon()
{
return 19.0;//具体的车跑到公里不一样
}
};
//给外部提供一个统一的获取汽车剩余路程数的API
void showCarleftMiles(Car &car)
{
cout << car.getName() << "left miles:" << car.getLeftMiles() << "公里" << endl;
}
int main()
{
Bnze b1("奔驰",20.0);
Audi a("奥迪",20.0);
BMW b2("宝马",20.0);
showCarleftMiles(b1);
showCarleftMiles(a);
showCarleftMiles(b2);
return 0;
}

- 继承纯虚函数,但没有重写
和普通的虚函数不同,在派生类中一般要对基类中纯虚函数进行重定义。如果该派生类没有对所有的纯虚函数进行重定义,则该派生类也会成为抽象类。这说明
- 只有protect构造没有public构造的类
除此以外,还有另外一种形式的抽象类。对一个类来说,如果只定义了protected型的构造函数而没有提供public构造函数,无论是在外部还是在派生类中作为其对象成员,但可以由其派生出新的类,这种能派生新类,却不能创建自己对象的类是另一种形式的抽象类。
class Base
{
protected:
Base(long base)
: _base(base)
{
cout << "Base()" << endl;
}
protected:
long _base;
};
class Derived
: public Base
{
public:
Derived(long base, long derived)
: Base(base)
, _derived(derived)
{
cout << "Derived(long, long)" << endl;
}
void print() const
{
cout << "_base:" << _base
<< ", _derived:" << _derived << endl;
}
private:
long _derived;
};
void test()
{
Base base(1);//error
Derived derived(1, 2);
}
为什么定义抽象类?抽象类和普通类的区别
抽象类的目的不是为了抽象一个实体的类型,主要目的:
- 让所有的派生类类通过继承基类直接复用该属性。(猫具有动物属性)
- 给所有的派生类保留统一的覆盖/重写接口;
语法上
- 拥有纯虚函数的类称为抽象类
- 抽象类不能实例化对象,但是可以定义指针和引用变量(指向派生类对象)
普通类定义指针,引用变量都可以,实例化对象也可以