bryce1010-ACM-Template
bryce1010-ACM-Template copied to clipboard
CPP primer
第 15 章 面向对象程序设计
面向对象程序设计的核心思想是: 数据抽象, 继承, 和动态绑定;
- 数据抽象: 将类的接口与实现分离;
- 继承: 可以定义相似的类型并对其相似的关系建模;
- 动态绑定: 程序执行时才选择函数的版本, 也称作运行时绑定;
继承: 基类, 派生类
虚函数
- 某些函数, 基类希望它的派生类各自定义适合自己的版本, 派生类必须对基类的内部的所有虚函数进行重定义, 声明的时候加上virtual;
- 基类有两种成员函数:
- 基类希望派生类进行覆盖的成员函数
- 基类希望派生类直接继承而不要改变的成员函数 虚函数指第一类,当使用基类的指针或者引用, 调用一个虚函数时, 执行动态绑定, 根据指针所绑定的不同对象, 选择不同版本的虚函数.
- virtual 关键字只能出现在类内,而不能用于类外部的函数定义.
- 成员函数如果没有被声明为virtual函数, 那么在编译的时候就发生解析, 而不是在运行的时候.
- protected: 希望派生类能访问, 而其他成员不能访问;
class A
{
public:
virtual void foo() // 派生类必须覆盖虚函数, 调用时执行动态绑定,声明只能在类内
{
cout<<"A::foo() is called"<<endl;
}
};
class B:public A
{
public:
void foo()
{
cout<<"B::foo() is called"<<endl;
}
virtual void foo() override; // c++11 提出override, 派生类允许不实现或者定义
protected:
int id; // 虚函数可以访问, 其他不能访问
};
int main(void)
{
A *a = new B();
a->foo(); // 在这里,a虽然是指向A的指针,但是被调用的函数(foo)却是B的!
return 0;
}
纯虚函数
纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”
virtual void funtion1()=0
- 为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。
- 在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。 编译器要求在派生类中必须予以重写以实现多态性。
抽象类
称带有纯虚函数的类为抽象类。 抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。如果派生类中没有重新定义纯虚函数,而只是继承基类的纯虚函数,则这个派生类仍然还是一个抽象类。如果派生类中给出了基类纯虚函数的实现,则该派生类就不再是抽象类了,它是一个可以建立对象的具体的类。 抽象类是不能定义对象的。
#include<iostream>
using namespace std;
const double PI=3.14159;
class Shapes //抽象类
{
protected:
int x, y;
public:
void setvalue(int d, int w=0){x=d;y=w;}
virtual void disp()=0;//纯虚函数
};
class Square:public Shapes
{
public:
void disp(){
cout<<"矩形面积:"<<x*y<<endl;
}
};
class Circle:public Shapes{
public:
void disp(){
cout<<"圆面积:"<<PI*x*x<<endl;
}
};
int main()
{
Shapes *ptr[2]; //定义对象指针数组
Square s1;
Circle c1;
ptr[0] = &s1;
ptr[0]->setvalue(10, 5);
ptr[0]->disp();
ptr[1] = &c1;
ptr[1]->setvalue(10);
ptr[1]->disp();
return 0;
}