函数重载,函数重定义(隐藏),函数重写(覆盖)

1.函数重载

同一作用域中,同名函数的形式参数(指参数的个数、类型或者顺序)不同时,构成函数重载。

Note:

  1. 这里没有说函数返回值类型;
  2. 类的静态成员函数与普通成员函数可以形成重载; 
  3. 函数重载发生在同一作用域,如类成员函数之间的重载、全局函数之间的重载。

2.函数重定义(隐藏)

函数隐藏指不同作用域中定义的同名函数构成函数隐藏(不要求函数返回值和函数参数类型相同)。比如派生类成员函数屏蔽与其同名的基类成员函数、类成员函数屏蔽全局外部函数。请注意,如果在派生类中存在与基类虚函数同返回值、同名且同形参的函数,则构成函数重写。

Note:

  1. 这里只有两点要求1.不同作用域;2.函数名相同;
  2. 不要求函数返回值,参数等相同。

3.函数重写(覆盖)

派生类中与基类同返回值类型、同名和同参数的虚函数重定义。

Note:

  1. 派生类和基类;
  2. 虚函数重定义;
  3. 返回值类型(特例:协变)。

测试码

parent.h

#pragma once
class Parent
{
  public:
    Parent(void);
    ~Parent(void);

  public:
    void say();
    int listen();
    void read();
    void write();
    void test(int);
};

---------------------------------------

parent.cpp

#include "StdAfx.h"
#include "Parent.h"

#include <iostream>


Parent::Parent(void)
{
}


Parent::~Parent(void)
{
}

void Parent::say()
{
  std::cout<< "父类 say()." << std::endl;
  return;
}

int Parent::listen()
{
  std::cout<< "父类 listen()." << std::endl;
  return 1;
}

void Parent::read()
{
  std::cout<< "父类 read()." << std::endl;
  return;
}

void Parent::write()
{
  std::cout<< "父类 write()." << std::endl;
}

void Parent::test(int b = 0)
{
  std::cout<< b << ":父类 test()." << std::endl;
}

-------------------------------------------------

son.h

#pragma once
#include "parent.h"
class Son :
  public Parent
{
  public:
    Son(void);
    ~Son(void);

  public:
    void say();
    char listen();  //隐藏父类的listen,即使返回值不同
    void write(int);  //隐藏父类的write,即使父类无参不同
    void test(char);  //隐藏父类的test,即使参数类型不同不同
};

 -------------------------------------

son.cpp

#include "StdAfx.h"
#include "Son.h"
#include <iostream>


Son::Son(void)
{
}


Son::~Son(void)
{
}

void Son::say()
{
  std::cout<< "子类 say()." << std::endl;
  return;
}

char Son::listen()
{
  std::cout<< "子类 listen()." << std::endl;
  return 'A';
}

void Son::write(int a)
{
  std::cout<< a << ":子类 write()." << std::endl;
}

void Son::test(char a = 'A')
{
  std::cout<< a << ":子类 test()." << std::endl;
}

-------------------------------------------------

test.cpp

#include "stdafx.h"
#include "Son.h"
#include <iostream>
using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
  Son Obj_son;
  Obj_son.say(); //输出子类的say()
  Obj_son.Parent::say(); //输出父类的say()
  Obj_son.listen(); //输出子类的say()
  Obj_son.Parent::listen(); //输出父类的say()
  std::cout<<"----------------"<<endl;
  Obj_son.read(); //输出父类的say()
  Obj_son.Parent::read(); //输出父类的say()
  //Obj_son.write(); //错误
  Obj_son.Parent::write();
  std::cout<<"----------------test"<<endl;
  Obj_son.test(5); //输出子类的test

  std::cout<<"----------------"<<endl;
  Parent Obj_parent;
  Obj_parent.say();
  //Obj_parent.Son::say(); //错误
  Obj_parent.listen();
  //Obj_parent.Son::listen(); //错误
  std::cout<<"----------------"<<endl;

  Parent *pParent = new Parent;
  Parent *pSon = new Son;
  pParent->say(); //输出父类的say()
  pSon->say(); //输出父类的say()
  ((Son *)pParent)->say(); //输出子类的say()
  ((Son *)pSon)->say(); //输出子类的say()
  std::cout<<"----------------"<<endl;
  pParent->listen(); //输出父类的listen()
  pSon->listen(); //输出父类的listen()
  ((Son *)pParent)->listen(); //输出子类的listen()
  ((Son *)pSon)->listen(); //输出子类的listen()
  std::cout<<"----------------"<<endl;
  pParent->read(); //输出父类的read()
  pSon->read(); //输出父类的read()
  ((Son *)pParent)->read(); //输出子类的read()
  ((Son *)pSon)->read(); //输出子类的read()
  std::cout<<"----------------"<<endl;
  pParent->write(); //输出父类的read()
  pSon->write(); //输出父类的read()
  //((Son *)pParent)->write(); //错误
  //((Son *)pSon)->write(); //错误

  std::cout<<"----------------指针2"<<endl;
  //Son *pParent1 = new Parent; //错误
  Son *pSon1 = new Son;
  //pParent1->say(); //输出父类的say()
  pSon1->say(); //输出子类的say()
  //((Son *)pParent1)->say(); //输出子类的say()
  ((Son *)pSon1)->say(); //输出子类的say()
  ((Parent *)pSon1)->say(); //输出父类的say()
  std::cout<<"----------------"<<endl;
  //pParent1->listen(); //输出父类的listen()
  pSon1->listen(); //输出子类的listen()
  //((Son *)pParent1)->listen(); //输出子类的listen()
  ((Son *)pSon1)->listen(); //输出子类的listen()
  ((Parent *)pSon1)->listen(); //输出父类的listen()
  std::cout<<"----------------"<<endl;
  //pParent1->read(); //输出父类的read()
  pSon1->read(); //输出父类的read()
  //((Son *)pParent1)->read(); //输出子类的read()
  ((Son *)pSon1)->read(); //输出父类的read()
  ((Parent *)pSon1)->read(); //输出父类的read()
  std::cout<<"----------------"<<endl;
  //pParent1->write(); //输出父类的read()
  //pSon1->write(); //输出子类的read(),完全不可能
  //((Son *)pParent1)->write(); //错误
  //((Son *)pSon1)->write(); //错误
  ((Parent *)pSon1)->write(); //输出父类write()
  getchar();
  return 0;
}

易混淆点:父类和派生类之间的函数重定义和函数重写。

分析原因:

  1. 作用域:父类与派生类;函数重定义作用域不仅仅是父类与派生类
  2. 名称:重定义和重写,从语义上理解很接近
posted @ 2019-05-07 23:48  N_zero  阅读(1267)  评论(0)    收藏  举报