关闭

c++多态特性的小小总结

标签: 函数面向对象继承多态c++
133人阅读 评论(0) 收藏 举报
分类:

1. 多态的含义:

多态是面向对象语言的重要特性,是指不同对象接收到同一消息时会产生不同的行为。是处理类的层次结构之间以及同一个类内部同名函数的关系问题。简单地说,多态就是在同一个类或继承体系结构的基类与派生类中,用同名函数来实现不同的功能。多态的概念比较复杂,有多种意义的多态,一个有趣但不严谨的说法是:继承是子类使用父类的方法,而多态则是父类使用子类的方法。一般,我们使用多态是为了避免在父类里大量重载引起代码臃肿且难于维护。

2. 概念:

重写(覆盖):两个函数具有相同函数名,返回类型,参数表。

重载:函数或者方法有相同的名称。

静态多态性:采用静态联编的方式实现的多态,所谓静态联编是通过函数重载和运算符重载实现的。

动态多态性:通过继承和虚函数,在程序执行时通过动态绑定实现的。

虚函数:我们知道当基类对象的指针指向派生类对象时,只能通过它访问到派生类中的基类子对象。虚函数只能在类中定义,即只能把类的成员函数声明为虚函数,不属于任何类的普通函数不能被定义为虚函数。虚函数的运行机制可以概括为:如果基类中的非静态成员函数被定义成为虚函数,且当派生类重写了该函数,当通过指向基类对象的指针或引用调用派生类对象中的虚函数时,就会调用该指针(或引用)实际所指对象的成员函数。一旦将某个成员函数声明为虚函数后,它在类的继承体系中就永远的为虚函数了。即派生类重写该函数是并没有把它声明为虚函数,它仍然为虚函数。
普通例子:

#include <iostream>
using namespace std;
class A{
public:
    virtual void print(){cout << "A...." <<endl;}//声明为虚函数
};
class B:public A{
public:
    void print(){cout << "B...." <<endl;}
};
class C:public B{
public:
    void print(){cout << "C...." <<endl;}
};
int main()
{
    A *pa;
    B b;
    A &rm = b;
    pa = &b;
    pa->print();
    rm.print();

    C c;
    A &rm1 = c;
    pa = &c;
    pa->print();
    rm1.print();
    return 0;
}

一种特殊形式:

#include <iostream>
using namespace std;
class B{
public:
    void f(){g();}
    virtual void g(){cout << "B:g()";}
};
class D:public B{
public:
    void g(){cout << "D:g()";}
};
int main()
{
    D d;
    d.f();
    return 0;
}

虚析构函数:c++允许将析构函数定义为虚函数(构造函数不能使虚函数),在继承体系结构中,如果基类的析构函数是虚函数,则所有的直接或间接从基类派生的类的析构函数都是虚函数。在销毁通过基类指针和引用调用的派生类对象时,虚析构函数可以确保能够彻底地对象占用的内存空间。在销毁自由存储空间中用new建立的对象时,虚析构函数可以确保在用delete销毁动态分配的派生类对象时调用到正确的析构函数,完成对象所占用空间的回收。典型情况是当用基类对象的指针或引用调用派生类对象时,如果基类析构函数不是虚函数,则通过基类指针或引用对派生类的析构很可能是不彻底的。

纯虚函数与抽象类:抽象类是通过纯虚函数来实现的。纯虚函数在基类中声明,但它在基类中没有具体的函数实现代码,要求继承它的派生类提供函数实现代码。在一个类中可以声明一个或多个纯虚函数,只要有纯虚函数的类就是抽象类。抽象类只能作为其他类的基类,不能用来建立对象,所以又叫抽象基类。可以通过抽象类对象的指针或引用访问到它的派生类对象,实现运行时的多态性。如果派生类只是简单地继承了抽象类的纯虚函数,而没有重现定义基类的纯虚函数,则派生类也是一个抽象类。

#include <iostream>
using namespace std;
class Figure{
protected:
    double x,y;
public:
    void set(double i,double j){x=i,y=j;}
    virtual void area() = 0;
};
class Triangle:public Figure{
public:
    void area(){cout << "三角形面积为:" << x*y*0.5<<endl;}
};
class Rectangle:public Figure{
public:
    void area(int i){cout << "矩形面积为:" << x*y <<endl;}
};
int main()
{
    Figure *pF;
    //Figure f1;//错误,因为抽象类不能实例化
    //Rectangle r1;//错误,因为它还是一个抽象类
    Triangle t;
    t.set(10,20);
    pF = &t;
    pF->area();
    Figure &rF = t;
    rF.set(20,20);
    rF.area();
    return 0;
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:24545次
    • 积分:838
    • 等级:
    • 排名:千里之外
    • 原创:60篇
    • 转载:6篇
    • 译文:0篇
    • 评论:7条
    文章分类
    最新评论