覆盖基类的函数

覆盖基类函数顾名思义就是在派生类中对基类的函数进行的重新定义。这里将会讲到下面的2个知识点:

1、隐藏基类的方法

2、调用基类的方法(隐式和显示调用基类的方法)

/*
*derive2.cpp
*Date : 2013-9-24
*Author: sjin
*Mail:413977243@qq.com
*/
#include <iostream>
#define N 0 using namespace std; /*知识点:
* 1、隐藏基类的方法(就是在派生类中重新实现函数的定义)
* 2、当基类的方法被覆盖时,仍可通过限定方法名来调用它,如下格式:
* baseclass::Method();
*/ /*基类*/
class Manmal{
public:
//Manmal():itsAge(2),itsWeight(5){ cout << " create Manmal object..."<<endl;}
//~Manmal(){cout << " destroy Manmal object..."<<endl;} void Move() const { cout << "Manmal move one step..." << endl;}
void Move(int distance) const
{
cout << "Manmal Move '" << distance << "' steps..." << endl;
} private:
int itsAge;
int itsWeight;
}; /*派生类*/
class Dog : public Manmal {
public:
//Dog() {cout << " create Dog object..." << endl;}
//~Dog() {cout << " destroy Dog object..."<< endl;} /*隐藏了基类的Move()方法*/
void Move() const
{
cout << "Dog move 5 steps..." << endl;
cout << "隐式调用基类方法(start):" << endl;
Manmal::Move();
Manmal::Move(1000);
cout << "隐式调用基类方法(end):" << endl;
} }; int main()
{
Manmal bigAnimal;
Dog Fido;
cout << "**********Manmal bigAnimal*************" << endl;
bigAnimal.Move();
bigAnimal.Move(2);
cout << "**********Dog Fido*************" << endl;
Fido.Move();
//Fido.Move(2);
/* 上面将会出现下面的错误
* derive2.cpp:56: error: no matching function for call to ‘Dog::Move(int)’
* derive2.cpp:43: note: candidates are: void Dog::Move() const
* 也就是说: 覆盖任一个重载的方法后,该方法的其他所有版本都会被隐藏。
* 如果补希望他们被隐藏,必须对其进行覆盖。
*/ /*显式调用被隐藏基类的方法*/
cout << "显式调用基类方法(start):" << endl;
Fido.Manmal::Move();
Fido.Manmal::Move(200);
cout << "显式调用基类方法(end):" << endl; }

输出如下:

**********Manmal bigAnimal*************
Manmal move one step...
Manmal Move '2' steps...
**********Dog Fido*************
Dog move 5 steps...
隐式调用基类方法(start):
Manmal move one step...
Manmal Move '1000' steps...
隐式调用基类方法(end):
显式调用基类方法(start):
Manmal move one step...
Manmal Move '200' steps...
显式调用基类方法(end):

虚方法

DOG对象是一个Manmal对象,因此这就意味着Dog对象继承了基类的属性和功能。C++扩展了其多态性,允许将派生类对象赋给指向基类的指针。因此,可以这样编写代码:

Manmal * pManmal = new Dog;

上面的代码创建了一个新的Dog对象,并返回了一个指向该对象的指针,然后将该指针赋给一个Manmal指针。之所以可以这样做,是因为狗也是一种动物。如果希望在调用被Dog覆盖的方法是,将调用正确的函数,虚函数让你能够做到这一点,要创建虚函数,在函数声明前加上关键字Virtual。看下面的代码:

/*
*virtual.cpp
*Date : 2013-9-20
*Author: sjin
*Mail:413977243@qq.com
*/
#include <iostream>
using namespace std; /*知识点:
* 1、如何创建虚函数?
* 在函数声明前加上virtual 关键字
* 2、使用虚方法的意义
* 基类中如果声明了虚方法,说明它的派生类中有可能会覆盖这个方法。
* 3、如果在基类中将一个成员方法标记为虚方法,还需要在派生类中将它标记为虚方法吗?
* 不需要,方法被声明为虚方法后,如果在派生类覆盖它,它仍是虚方法。在派生类继续
* 将其标记为虚方法是个不错的主意,但是没有必要这么作,这样使代码更容易理解。
* */ class Manmal {
public:
Manmal():itsAge() { cout << "Manmal constrctor...\n";}
virtual ~Manmal() { cout << "Manmal destructor...\n";}
void Move() const { cout << "Manmal move one step\n";}
virtual void Speak() const { cout << "Manmal speak!\n";} protected:
int itsAge;
}; class Dog :public Manmal{
public:
Dog() { cout << " Dog constrctor...\n";}
virtual ~Dog() { cout << " Dog destructor..\n";}
void WagTail() { cout << " Wagging Tail...\n";}
void Speak() const { cout << "Dog woof!\n";}
void Move() const { cout << "Dog moves 5 steps ...\n";}
}; int main()
{
/*创建一个信的dog对象,并返回该对象的指针,然后将该指针付给一个
* Manmal指针。
* 这是多态的本质,例如:可创建很多类型的窗口,包括对话框,可滚动
* 窗库和列表框,然后给每种窗口定义一个虚方法draw().通过创建一个窗口指针,
* 并将对话框和其他的派生对象赋給指针,就可以通过调用draw(),而不用考虑运行
* 时指针只想的实际对象类型,程序将调用正确的draw()方法。
* */ Manmal *pDog = new Dog;
pDog->Move();
pDog->Speak();/*虚方法,被覆盖*/
/*释放对象*/
delete pDog;
return 0;
}

输出:

Manmal constrctor...
Dog constrctor...
Manmal move one step
Dog woof!
Dog destructor..
Manmal destructor...

从上面的输出可以看到,Manmal 指针pDog ,调用了Dog类的SPEAK()方法,这里很神奇!但是Move()函数调用的仍然是manmal类的方法。


走进C++程序世界-----继承和派生(2)的更多相关文章

  1. 走进C++程序世界------继承和派生

    继承和派生 继承是面向对象编程语言的最重要方面之一,正确的使用继承可编写出设计良好,容易于维护和扩展的应用程序.下面是在其他博客中的总结: ****************************** ...

  2. 走进C++程序世界------异常处理

    一. 概述 C++自身有着很强的纠错能力,发展到现在,已经建立了比較完好的异常处理机制. C++的异常情况无非两种,一种是语法错误.即程序中出现了错误的语句,函数.结构和类,致使编译程序无法进行.还有 ...

  3. 走进C++程序世界-----函数相关(全局变量)

    全局变量 在函数外面定义的变量的作用域为全局,在程序的任何函数中都可用.与全局变量同名的局部变量不会修改全局变量的值,但会隐藏它.如果函数中有一个与全局变量同 名的局部变量时,则在函数中使用该名称时, ...

  4. 走进C++程序世界------IO标准库介绍

    流概述    流是C++标准的组成部分,流的主要目标是,将从磁盘读取文件或将输入写入控制台屏幕的问题封装起来,创建流后程序猿就能够使用它.流将负责处理全部的细节. IO类库 在C++输入、输出操作是通 ...

  5. 走进C++程序世界-------类的定义和使用(数据成员和方法成员,析构函数,构造函数,内联实现)

    类的成员简介 在C++中,可以通过声明一个类来穿件一种新的类型.类将一组变量(他们的类型通常不同)和一组相关的函数组合在一起.类可以有各种类型的变量组成,还可以包含其他类对象.成员变量称为数据成员它们 ...

  6. 走进C++程序世界-----operator new delete 重载

     在C++ 的世界里,new 和delete 是keyword.而在C的世界里相相应的malloc和free是函数,关键C++的new和delete分析,详见前面的章节.这里就不在过多的介绍了.链接. ...

  7. 程序设计实习MOOC / 继承和派生——编程作业 第五周程序填空题1

    描述 写一个MyString 类,使得下面程序的输出结果是: 1. abcd-efgh-abcd- 2. abcd- 3. 4. abcd-efgh- 5. efgh- 6. c 7. abcd- 8 ...

  8. [C#] 走进 LINQ 的世界

    走进 LINQ 的世界 序 在此之前曾发表过三篇关于 LINQ 的随笔: 进阶:<LINQ 标准查询操作概述>(强烈推荐) 技巧:<Linq To Objects - 如何操作字符串 ...

  9. C#7.2——编写安全高效的C#代码 c# 中模拟一个模式匹配及匹配值抽取 走进 LINQ 的世界 移除Excel工作表密码保护小工具含C#源代码 腾讯QQ会员中心g_tk32算法【C#版】

    C#7.2——编写安全高效的C#代码 2018-11-07 18:59 by 沉睡的木木夕, 123 阅读, 0 评论, 收藏, 编辑 原文地址:https://docs.microsoft.com/ ...

随机推荐

  1. FFT初步学习小结

    FFT其实没什么需要特别了解的,了解下原理,(特别推荐算法导论上面的讲解),模板理解就行了.重在运用吧. 处理过程中要特别注意精度. 先上个练习的地址吧: http://vjudge.net/vjud ...

  2. [unity菜鸟] 修改发布成web后的logo

    1. 原始效果  (tip:在4.x的书中有介绍) 2. 打开.html文件原始代码如下 <script type='text/javascript' src='jquery.min.js'&g ...

  3. SPRING IN ACTION 第4版笔记-第四章ASPECT-ORIENTED SPRING-002-AOP术语解析

    一. 1.Advice Advice是切面的要做的操作,它定义了what.when(什么时候要做什么事) aspects have a purpose—a job they’re meant to d ...

  4. RAM云存储已经出现了,就是特别贵

    据说bat有这种全内存的服务器集群, RAM的问题是,容量上去了就会很费电,而且不方便做持久化,并且成本也不低,一般只能作为缓存.内存数据库,给bat.12306这种高富帅用 也有提供内存云存储的服务 ...

  5. str.match(regex)与regex.exec(str)对比解析,从此不再晕

    match属于字符串的方法,exec属于正则表达式的方法.其中regex是否有g标志的区别经常搞不清,所以测试记录下. 1.str.match(regex) regex中无g标志 返回一个数组,arr ...

  6. Nagios‘process_cgivars()’函数差一错误拒绝服务漏洞

    漏洞名称: Nagios‘process_cgivars()’函数差一错误拒绝服务漏洞 CNNVD编号: CNNVD-201312-495 发布时间: 2013-12-27 更新时间: 2013-12 ...

  7. 做一个自己的最小Linux系统

     一.前言 Linux操作系统至1991.10.5号诞生以来,就源其开源性和自由性得到了很多技术大牛的青睐,每个Linux爱好者都为其贡献了自己的一份力,不管是在Linux内核还是开源软件等方面,都为 ...

  8. MySQL运行原理与基础架构

    1.MySQL基础 MySQL是一个开放源代码的关系数据库管理系统.原开发者为瑞典的MySQL AB公司,最早是在2001年MySQL3.23进入到管理员的视野并在之后获得广泛的应用. 2008年My ...

  9. lihgtoj 1006

    记忆化搜索下即可. #include<cstdio> #include<string> #include<cstring> #include<iostream ...

  10. Java笔记(九)……面向对象I

    面向对象概念 理解面向对象 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程 强调的是功能行为 面向对象 将功能封装进对象,强调具备了功能的对象. 面向对象是基于面向过程的. 面向 ...