函数重载、覆盖、多态

#include <iostream>

using namespace std;

/*
 *对于纯虚函数可以实现也可以不实现,但派生类一定要覆盖基类的纯虚函数.否则派生类仍然是抽象类
 *
 *如果派生类覆盖基类的虚函数,则基类的指针或引用实际指向子类对象,那么通过该指针或引用调用虚函数时,将调用子类的虚函数;如果不是虚函数,则调用父类的函数.
 *
 */
class PEOPLE
{
public:
    int age;
    //派生类必须实现抽象类的纯虚函数,否则派生类仍然是抽象类
    virtual void speak() =0;
    virtual void play();
    virtual void play(int);
    void eat();
};

void PEOPLE::speak()
{
    cout << "PEOPLE speak..." << endl;
}

void PEOPLE::eat()
{
    cout << "PEOPLE eat..." << endl;
}

void PEOPLE::play()
{
    cout << "PEOPLE play..." << endl;
}

void PEOPLE::play(int id)
{
    cout << "PEOPLE play, id=" << id << endl;
}

class STUDENT :public PEOPLE
{
    public:
        STUDENT()
        {
            id = 1;
        }

        void speak()
        {
            cout << "stu speak..."<< endl;
        }

        void eat()
        {
            cout << "stu eat" << endl;
        }

        void play()
        {
            cout << "stu play..." << endl;
        }

        void play(int id)
        {
            cout << "stu play, id = " << id << endl;
        }

        int id;

};

int main(int argc, char** argv)
{
    //抽象类不能实例化
    //PEOPLE p;
    //cout << "sizeof PEOPLE:" << sizeof(p) << endl;

    STUDENT stu;
    cout << "sizeof STUDENT:" << sizeof(stu) << endl;
    cout << "stu addr:" << &stu << endl;
    stu.age = 1;
    cout << "stu age:" << stu.age << "    age addr:" << &stu.age << endl;
    cout << "stu id:" << stu.id << "    id addr:" << &stu.id << endl;

    STUDENT* pstu = &stu;
    PEOPLE* p = &stu;
    cout << "p=" << p << endl;
    cout << "age:" << p->age << "    age addr:" << &p->age << endl;
    //派生类必须实现纯虚函数speak();
    p->speak();
    //仍然调用基类的非虚函数,没有多态特性
    p->eat();
    pstu->eat();
    //若派生类没有覆盖基类的虚函数play(),那么调用基类的play();
    //若派生类覆盖了基类的虚函数play(),那么调用派生类的play()
    p->play();
    pstu->play();

    p->play(10);
    pstu->play(10);

    //函数重载是类内部同名函数之间的关系,函数覆盖是父子类虚函数之间的关系
    return 0;
}
时间: 2024-10-08 10:39:21

函数重载、覆盖、多态的相关文章

C++多态篇2——虚函数表详解之从内存布局看函数重载,函数覆盖,函数隐藏

上一篇C++多态篇1一静态联编,动态联编.虚函数与虚函数表vtable中,我在最后分析了虚函数与虚函数表的内存布局,在下一篇详细剖析虚函数及虚函数表的过程中,我发现有关函数重载,函数覆盖,函数重写和函数协变的知识也要理解清楚才能对虚函数表在内存中的布局,对派生类的对象模型以及对多态的实现有更深的理解. 所以这一篇我作为一篇过渡篇,也同时对我以前写过的一篇博文进行一个收尾.在C++继承详解之二--派生类成员函数详解(函数隐藏.构造函数与兼容覆盖规则)文章中,我对函数覆盖,重载,重写提了一下,但是没

函数重载和覆盖(重写)的区别

1.重载:函数重载是指在同一作用域内(名字空间),可以有一组具有相同函数名,不同参数列表的函数: 2.覆盖(也叫重写):指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现.即函数名和参数都一样,只是函数的实现体不一样: 3.隐藏:指派生类中的函数把基类中相同名字的函数屏蔽掉了,隐藏与另外两个概念表面上看来很像,很难区分,其实他们的关键区别就是在多态的实现上. 下面那种情形下myfunc函数声明是重载? A. namespace IBM { int myfunc(int a); } name

C++ 类的多态二(函数重载--函数重写--函数重定义)

//函数重载--函数重写--函数重定义 #include<iostream> using namespace std; /* 函数重载: 必须在一个类中进行(子类无法重载父类中的函数) 子类无法重载父类的函数,父类同名函数将被子类的同名函数覆盖 重载是在编译期间根据参数类型,顺序,个数决定的函数调用 函数重写 必须发生于父类和子类之间 并且父类和子类中的函数必须有完全相同的函数签名 使用virtual声明之后能够产生多态(如果不使用virtual,那叫重定义) 多态是在运行期间根据具体对象的类

C++:区别覆盖,重载与多态

覆盖:在基类中定义了一个非虚拟函数,然后在派生类中又定义了一个同名同参数同返回类型的函数,这就是覆盖了.在派生类对象上直接调用这个函数名,只会调用派生类中的那个.重载:在基类中定义了一个非虚拟函数,然后在派生类中定义一个同名,但是具有不同的参数表的函数,这就是重载.在派生类对象上调用这几个函数时,用不同的参数会调用到不同的函数,有可能会直接调用到基类中的那个.多态:在基类中定义了一个虚拟函数,然后在派生类中又定义一个同名,同参数表的函数,这就是多态.多态是这3种情况中唯一采用动态绑定技术的一种情

Java学习资料-方法覆盖、方法重载、多态与动态绑定

1.方法覆盖 方法覆盖就是子类定义一个和父类同名的方法来覆盖父类的方法.当父类方法在某些子类中被覆盖后,通常是子类调用父类,并做一些额外的其它工作. 使用方法覆盖应注意下面一些事项: 不使用super而希望引用父类方法会导致无限的递归,因为子类方法实际上是在调用它自己. 当通过父类引用调用一个方法时,Java会正确地选择与那个对象对应的类的覆盖方法.对于父类提供的方法,子类可以覆盖它,但这不是必须的,即子类也可以使用一个方法的父类版本. 方法覆盖中,子类在重新定义父类已有的方法时,应保持与父类完

函数模板,函数模板重载,可变参数模板,函数模板覆盖,通过引用交换数据

 1.函数模板初级,如果想使用模板,需要实例化,实例化的方式是加上<数据类型> #include <iostream> //函数模板可以对类型进行优化重载,根据类型会覆盖 //如果仍然要使用模板函数,需要实例化 template<class T> T add(T a, T b) { std::cout << "T add " << std::endl; return a + b; } int add(int a, int

对比C++与Java中的函数重载、覆盖、和隐藏

                                  在C++中 1.函数的重载 C++中的函数的重载要求的是  函数名相同 参数列表必须不同  返回值类型可以相同也可以不相同:只有参数列表不相同,在函数调用时,编译环境才能准确抉择调用的是哪个函数.例如:void display():void display(int  i);void dispaly(double  i);void  display(int i,double i); void display(double  i,i

java中的覆盖,重载和多态

今天来介绍java中的三大强功能覆盖,重载和多态. 方法覆盖:当一个子类继承了一个父类时,它也同时继承了父类的属性和方法,可以直接使用父类的属性和方法,或者,如果父类的方法不能满足子类的需求,则可以在子类中对父类的方法进行"改造"即覆盖.在覆盖的过程中,需要提供和父类中的被覆盖方法相同的方法名称,输入参数以及返回类型.另外,在子类对父类的方法进行覆盖的过程中,不能使用比父类中的被覆盖方法更严格的访问权限,例如父类中方法的修饰符为public,则子类的覆盖方法不能用protected,d

0607pm克隆&amp;引用类&amp;加载类&amp;面向对象串讲&amp;函数重载

克隆class Ren{ public $name; public $sex; function __construct($n,$s) { $this->name=$n; $this->sex=$s; } function __clone()//改变克隆的对象内容 { $this->name="李思思";//this代表复本对象 $that->name="李思思";//that代表原本的,后来废弃了 }}$r=new Ren("张丹