北大程序设计与算法(三)
实现自vs2019
描述
#include <iostream>
using namespace std;
// 在此处补充你的代码
void print() {
cout << Animal::number << " animals in the zoo, " << Dog::number << " of them are dogs, " << Cat::number << " of them are cats" << endl;
}
int main() {
print();
Dog d1, d2;
Cat c1;
print();
Dog* d3 = new Dog();
Animal* c2 = new Cat;
Cat* c3 = new Cat;
print();
delete c3;
delete c2;
delete d3;
print();
}
输入
无
输出
0 animals in the zoo, 0 of them are dogs, 0 of them are cats
3 animals in the zoo, 2 of them are dogs, 1 of them are cats
6 animals in the zoo, 3 of them are dogs, 3 of them are cats
3 animals in the zoo, 2 of them are dogs, 1 of them are cats
样例输入
None
样例输出
0 animals in the zoo, 0 of them are dogs, 0 of them are cats
3 animals in the zoo, 2 of them are dogs, 1 of them are cats
6 animals in the zoo, 3 of them are dogs, 3 of them are cats
3 animals in the zoo, 2 of them are dogs, 1 of them are cats
实现
class Animal{
public:
static int number;
Animal(){
number++;
}
virtual~Animal(){
number--;
}
};
class Dog:public Animal{
public:
static int number;
Dog(){
number++;
}
~Dog(){
number--;
}
};
class Cat:public Animal{
public:
static int number;
Cat(){
number++;
}
~Cat(){
number--;
}
};
int Dog::number=0;
int Animal::number=0;
int Cat::number=0;
要点
1.Animal* c2 = new Cat;
delete基类指针,会调用基类析构函数。
基类指针指向的派生类对象,分配的是派生类对应的内存空间,所以还要调用派生类的析构函数。但是编译器不知道它需要调用派生类析构函数,这就产生了问题。所以我们要把基类的析构函数声明为virtual,将调用相应对象类型的析构函数,因此,如果指针指向的是子类对象,将调用子类的析构函数,然后自动调用基类的析构函数。注意派生类的析构函数 vitural可以不进行声明。
定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。
2.多态的表现形式之一即基类指针指向派生类对象时,那么被调用的是派生类的虚函数。
静态变量和全局变量的区别
https://blog.csdn.net/u012149181/article/details/83421563
补一点虚函数多态的东西
1.虚函数是C++中用于实现多态的机制。
核心理念就是通过基类访问派生类定义的函数。
2.在很多情况下,基类本身生成对象是不合情理的。
例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。
引入纯虚函数,将函数定义为纯虚函数
(virtual ReturnType Function()= 0;)
编译器要求在派生类中必须予以重写以实现多态性。
同时含有纯虚拟函数的类称为抽象类,抽象类不能定义实例,但可以声明指向实现该抽象类的具体类的指针或引用。
定义纯虚函数的目的在于,使派生类仅仅只是继承函数的接口。
纯虚函数的意义,让所有的类对象(主要是派生类对象)
都可以执行纯虚函数的动作,但类无法为纯虚函数提供一个合理的缺省实现。所以类纯虚函数的声明就是在告诉子类的设计者,“你必须提供一个纯虚函数的实现,但我不知道你会怎样实现它”。详见
纯虚函数与虚函数
描述
Shape基类,派生出矩形类和圆形类。
#include <iostream>
using namespace std;
class Shape {
public:
virtual double GetArea() = 0;
virtual void Print() = 0;
};
class Retangle :public Shape {
public:
int w, h;
virtual double GetArea();
virtual void Print();
};
class Circle :public Shape {
public:
int r;
virtual double GetArea();
virtual void Print();
};
double Retangle::GetArea() {
return w * h;
}
double Circle::GetArea() {
return 3.14 * r * r;
}
void Retangle::Print() {
cout << "Retangle:"<<GetArea()<<endl;
}
void Circle::Print() {
cout << "Circle:" << GetArea() << endl;
}
int main() {
Retangle *pr1=new Retangle;
Retangle* pr2=new Retangle;
Circle *pc=new Circle;
cout<<"请输入矩形1长和宽"<<endl;
cin >> pr1->w >> pr1->h ;
cout<<"请输入矩形2长和宽"<<endl;
cin >> pr2->w >> pr2->h;
cout<<"请输入圆的半径"<<endl;
cin >> pc->r;
pr1->Print();
pr2->Print();
pc->Print();
}