bryce1010-ACM-Template icon indicating copy to clipboard operation
bryce1010-ACM-Template copied to clipboard

CPP primer

Open Bryce1010 opened this issue 4 years ago • 1 comments

Bryce1010 avatar Apr 25 '20 02:04 Bryce1010

第 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;

}

Bryce1010 avatar Apr 25 '20 02:04 Bryce1010