当前位置:七道奇文章资讯编程技术VC/C++编程
日期:2011-03-22 13:55:00  来源:本站整理

高质量C++/C编程指南-第8章-C++函数的高级特点(3)[VC/C++编程]

赞助商链接



  本文“高质量C++/C编程指南-第8章-C++函数的高级特点(3)[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

8.2.2 令人迷惑的躲藏法则

本来仅仅辨别重载与覆盖并不算艰难,但是C++的躲藏法则使问题复杂性陡然增添.这里“躲藏”是指派生类的函数屏蔽了与其同名的基类函数,法则以下:

(1)假如派生类的函数与基类的函数同名,但是参数差别.此时,不管有没有virtual关键字,基类的函数将被躲藏(注意别与重载混合).

(2)假如派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字.此时,基类的函数被躲藏(注意别与覆盖混合).

示例程序8-2-2(a)中:

(1)函数Derived::f(float)覆盖了Base::f(float).

(2)函数Derived::g(int)躲藏了Base::g(float),而不是重载.

(3)函数Derived::h(float)躲藏了Base::h(float),而不是覆盖.

#include <iostream.h>

class Base

{

public:

virtual void f(float x){ cout << "Base::f(float) " << x << endl; }

void g(float x){ cout << "Base::g(float) " << x << endl; }

void h(float x){ cout << "Base::h(float) " << x << endl; }

};

class Derived : public Base

{

public:

virtual void f(float x){ cout << "Derived::f(float) " << x << endl; }

void g(int x){ cout << "Derived::g(int) " << x << endl; }

void h(float x){ cout << "Derived::h(float) " << x << endl; }

};

示例8-2-2(a)成员函数的重载、覆盖和躲藏

据作者观察,很多C++程序员没有意识到有“躲藏”这回事.由于熟习不够深化,“躲藏”的发生可谓神出鬼没,常常产生令人迷惑的后果.

示例8-2-2(b)中,bp和dp指向同一地址,按理说运行后果应当是相同的,可事实并非这样.

void main(void)

{

Derived d;

Base *pb = &d;

Derived *pd = &d;

// Good : behavior depends solely on type of the object

pb->f(3.14f); // Derived::f(float) 3.14

pd->f(3.14f); // Derived::f(float) 3.14

// Bad : behavior depends on type of the pointer

pb->g(3.14f); // Base::g(float) 3.14

pd->g(3.14f); // Derived::g(int) 3 (surprise!)

// Bad : behavior depends on type of the pointer

pb->h(3.14f); // Base::h(float) 3.14 (surprise!)

pd->h(3.14f); // Derived::h(float) 3.14

}

示例8-2-2(b) 重载、覆盖和躲藏的对比

8.2.3 摆脱躲藏

躲藏法则惹起了不少麻烦.示例8-2-3程序中,语句pd->f(10)的本意是想调用函数Base::f(int),但是Base::f(int)不幸被Derived::f(char *)躲藏了.由于数字10不能被隐式地转化为字符串,所以在编译时出错.

class Base

{

public:

void f(int x);

};

class Derived : public Base

{

public:

void f(char *str);

};

void Test(void)

{

Derived *pd = new Derived;

pd->f(10); // error

}


示例8-2-3 由于躲藏而招致错误

从示例8-2-3看来,躲藏法则仿佛很笨拙.但是躲藏法则至少有两个存在的来由:

u 写语句pd->f(10)的人大概真的想调用Derived::f(char *)函数,只是他误将参数写错了.有了躲藏法则,编译器便可以明确指出错误,这未必不是功德.不然,编译器会静暗暗地将错就错,程序员将很难发现这个错误,流下祸根.

u 假定类Derived有多个基类(多重担当),有时搞不清楚哪些基类定义了函数f.假如没有躲藏法则,那么pd->f(10)大概会调用一个出其不意的基类函数f.固然躲藏法则看起来不怎么有原理,但它的确能清除这些不测.

示例8-2-3中,假如语句pd->f(10)一定要调用函数Base::f(int),那么将类Derived改正成以下便可.

class Derived : public Base

{

public:

void f(char *str);

void f(int x) { Base::f(x); }

};


  以上是“高质量C++/C编程指南-第8章-C++函数的高级特点(3)[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
  • <b>高质量C++/C编程指南-第7章-内存管理(6)</b>
  • 高质量C++/C编程指南-第7章-内存管理(7)
  • 高质量C++/C编程指南-第8章-C++函数的高级特点(1)
  • 高质量C++/C编程指南-第8章-C++函数的高级特点(2)
  • 高质量C++/C编程指南-第8章-C++函数的高级特点(3)
  • <b>高质量C++/C编程指南-第8章-C++函数的高级特点(4)</b>
  • <b>高质量C++/C编程指南-第9章-类的构造函数、析构函数与赋值函数(1</b>
  • 高质量C++/C编程指南-第9章-类的构造函数、析构函数与赋值函数(2
  • 高质量C++/C编程指南-第9章-类的构造函数、析构函数与赋值函数(3
  • 高质量C++/C编程指南-第9章-类的构造函数、析构函数与赋值函数(4
  • <b>高质量C++/C编程指南-第10章-类的担当与组合(1)</b>
  • 高质量C++/C编程指南-第10章-类的担当与组合(2)
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .