父类定义的指针可以指向子类对象;
指针会误以为,他们指向的对象是Base1类型,导致错误;
如何实现多态:
1.创建类的继承关系图
2.所以类对象都可以调用的这个函数
3.创建父类指针数组
4.子类的地址赋给父类指针
5.指针调用虚函数
和多态其实是一个概念
动态绑定我们是无法在运行之前,事先知道运行的结果是不知道的;
不仅是指针,引用也可以!
指针和引用可以,但最后一种情况无法实现多态
创建的时候是先创建base再创建derived的;这个时候,不加virtual 的话会导致,只delete了base,但没有delete掉derived;
建议所有析构函数都加virtual
只有用new去创建的时候,才有可能出现这种错误。
对于暂时无法实现的函数,我们可以定义为纯虚函数,留给派生类去实现;
定义了纯虚函数的类叫抽象类;
抽象类只能作为基类来使用;
构造函数不能是虚函数,析构函数可以是虚函数;
main.cpp
#include "shape.h"
#include "circle.h"
#include "rectangle.h"
#include "roundrectangle.h"
#include
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(void) {
shape *ptrShape[6];
circle circle1;
circle circle2("red",2);
Rectangle Rectangle1,Rectangle2("green",2,3);
RoundRectangle RoundRectangle1,RoundRectangle2("yelow",2,3,1);
ptrShape[0] = &circle1;
ptrShape[1] = &circle2;
ptrShape[2] = &Rectangle1;
ptrShape[3] = &Rectangle2;
ptrShape[4] = &RoundRectangle1;
ptrShape[5] = &RoundRectangle2;
// ptrShape[0] = new circle;
// ptrShape[1] = new Rectangle;
// ptrShape[2] = new RoundRectangle;
// ptrShape[3] = new circle("red",2);
// ptrShape[4] = new Rectangle("red",2,3);
// ptrShape[5] = new RoundRectangle("red",2,3,1);
for(int i=0;i<6;i++){
cout<<"该图形面积为:"<<ptrShape[i]->getArea()<<endl;
}
return 0;
}
shape.cpp
#include "shape.h"
#include
using namespace std;
shape::shape():color("white"){
cout<<"无参创建shape"<<endl;
}
shape::shape(string color){
this->color = color;
cout<<"有参创建shape"<<endl;
}
shape::~shape(){
cout<<"消亡shape"<<endl;
}
string shape::getColor(){
return this->color;
}
void shape::setColor(char color){
this->color = color;
}
void shape::display(){
cout<<"color:"<<getColor()<<endl;
}
shape.h
#ifndef SHAPE_H
#define SHAPE_H
#include
#include
using namespace std;
class shape{
private:
string color;
public:
shape();
shape(string color);
virtual ~shape(); //析构函数+virtual
string getColor();
void setColor(char color);
void display();
virtual double getArea()=0; //纯虚函数,变成抽象类
};
#endif
circle.cpp
#include "circle.h"
#include "shape.h"
#include
const double pi = 3.14;
circle::circle(){
radius = 1;
cout<<"无参创建circle"<<endl;
}
circle::circle(string color,double radius):shape(color){
this->radius = radius;
cout<<"有参创建circle"<<endl;
}
circle::~circle(){
cout<<"消亡circle"<<endl;
}
double circle::getRadius(){
return this->radius;
}
void circle::setradius(double radius){
this->radius = radius;
}
double circle::getArea(){
return pi*radius*radius;
}
void circle::display(){
shape::display();
cout<<"R="<<getRadius()<<","<<"Area="<<getArea()<<endl;
}
circle.h
#ifndef CIRCLE_H
#define CIRCLE_H
#include
#include "shape.h"
class circle:public shape{
private:
double radius;
public:
circle();
circle(string color,double radius);
virtual ~circle();
void setradius(double radius);
double getRadius();
double getArea();
void display();
};
#endif
rectangle.cpp
#include "rectangle.h"
#include "shape.h"
#include
Rectangle::Rectangle(){
width = 1;
height = 1;
cout<<"无参创建Rectangle"<<endl;
}
Rectangle::Rectangle(string color,double width,double height):shape(color){
this->width = width;
this->height = height;
cout<<"有参创建Rectangle"<<endl;
}
Rectangle::~Rectangle(){
cout<<"消亡Rectangle"<<endl;
}
double Rectangle::getWidth(){
return width;
}
double Rectangle::getHeight(){
return height;
}
void Rectangle::setWidth(double width){
this->width = width;
}
void Rectangle::setHeight(double height){
this->height = height;
}
double Rectangle::getArea(){
return width*height;
}
void Rectangle::display(){
shape::display();
cout<<"width="<<getWidth()<<","<<"Height="<<getHeight()<<","<<"Area="<<getArea()<<endl;
}
rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
#include
#include "shape.h"
class Rectangle:public shape{
private:
double width;
double height;
public:
Rectangle();
Rectangle(string color,double width,double height);
virtual ~Rectangle();
void setWidth(double width);
void setHeight(double height);
double getWidth();
double getHeight();
double getArea();
void display();
};
#endif
roundrectangle.cpp
#include "roundrectangle.h"
#include "rectangle.h"
#include"shape.h"
#include
RoundRectangle::RoundRectangle(){
this->roundRadius = 1;
cout<<"无参创建RoundRectangle"<<endl;
}
RoundRectangle::RoundRectangle(string color,double width,double height,double roundRadius):Rectangle(color,width,height){
this->roundRadius = roundRadius;
cout<<"有参创建RoundRectangle"<<endl;
}
RoundRectangle::~RoundRectangle(){
cout<<"消亡RoundRectangle"<<endl;
}
double RoundRectangle::getRoundradius(){
return roundRadius;
}
void RoundRectangle::setRoundradius(double roundRadius){
this->roundRadius = roundRadius;
}
double RoundRectangle::getArea(){
return Rectangle::getWidth()*Rectangle::getHeight()+(3.14*roundRadius*roundRadius)/2;
}
void RoundRectangle::display(){
shape::display();
cout<<"width="<<Rectangle::getWidth()<<","<<"Height="<<Rectangle::getHeight()<<","<<"Area="<<getArea()<<endl;
}
roundrectangle.h
#ifndef ROUNDRECTANGLE_H
#define ROUNDRECTANGLE_H
#include
#include "rectangle.h"
class RoundRectangle:public Rectangle{
private:
double roundRadius;
public:
RoundRectangle();
RoundRectangle(string color,double width,double height,double roundRadius);
virtual ~RoundRectangle();
void setRoundradius(double roundRadius);
double getRoundradius();
double getArea();
void display();
};
#endif
(1)必须要定义,因为getArea()是纯虚函数,派生类必须补全他的函数实现,否则Circle也会变成抽象类,无法创建对象
(2)不会,因为它可以调用他的父类Rectangle类的getArea(),编译不出错,但内容是错误的
(3)可以。但
#include "shape.h"
#include "circle.h"
#include "rectangle.h"
#include "roundrectangle.h"
#include
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
double sumArea(shape* shapes[],int n){
double sum = 0;
for(int i = 0 ;i<n;i++){
sum += shapes[i]->getArea();
}
}
int main(void) {
shape *ptrShape[6];
circle circle1;
circle circle2("red",2);
Rectangle Rectangle1,Rectangle2("green",2,3);
RoundRectangle RoundRectangle1,RoundRectangle2("yelow",2,3,1);
ptrShape[0] = &circle1;
ptrShape[1] = &circle2;
ptrShape[2] = &Rectangle1;
ptrShape[3] = &Rectangle2;
ptrShape[4] = &RoundRectangle1;
ptrShape[5] = &RoundRectangle2;
// ptrShape[0] = new circle;
// ptrShape[1] = new Rectangle;
// ptrShape[2] = new RoundRectangle;
// ptrShape[3] = new circle("red",2);
// ptrShape[4] = new Rectangle("red",2,3);
// ptrShape[5] = new RoundRectangle("red",2,3,1);
for(int i=0;i<6;i++){
cout<<"该图形面积为:"<<ptrShape[i]->getArea()<<endl;
}
cout<<"总面积"<<sumArea(ptrShape,6)<<endl;
return 0;
}