《C++ Primer》第15章 15.6节习题答案

《C++ Primer》第15章 面向对象程序设计

除了覆盖继承而来的虚函数之外,派生类最好不要重用其他定义在基类中的名字。

如果派生类(即内层作用域)的成员与基类(即外层作用域)的某个成员同名,则派生类将在其作用域内隐藏该基类成员。即使用派生类成员和基类成员的形参列表不一致。基类成员也仍然会被隐藏掉:

#include <iostream>

using std::endl;
using std::cout;

struct Base
{
    int memfcn()
    {
        std::cout << "Base============memfcn()====" << endl;
        return 0;
    }
    virtual int memfcn2()
    {
        std::cout << "Base============memfcn2()===" << endl;
        return 0;
    }
    int memfcn3() const
    {
        std::cout << "Base============memfcn()====" << endl;
        return 0;
    }
};

struct Derived: public Base
{
    int memfcn(int a) //隐藏基类的memfcn
    {
        std::cout << "Derived=========memfcn(a)===" << a << endl;
        return a;
    }
    int memfcn2(int a)
    {
        std::cout << "Derived=========memfcn2(a)==" << a << endl;
        return 0;
    }
    int memfcn3(int a)
    {
        std::cout << "Derived=========memfcn3(a)==" << a << endl;
        return 0;
    }
};

int main()
{
    Derived d;
    Base b;
    b.memfcn();//调用Base::memfcn
    d.memfcn(10);//调用Derived::memfcn
    //d.memfcn();//错误:参数列表为空的memfcn被隐藏了
    d.Base::memfcn();//正确,调用Base::memfcn
    cout << endl;
    b.memfcn2();
    //d.memfcn2();//错误:参数列表为空的memfcn2被隐藏了
    cout << endl;
    b.memfcn3();
    //d.memfcn3();//错误:参数列表为空的memfcn3被隐藏了
    return 0;
}

运行结果:

 

15.6节 继承中的类作用域 习题答案

练习15.23:假设第550页的D1类需要覆盖它继承而来的fcn函数,你应该如何对其进行修改?如果你修改之后fcn匹配了Base中的定义,则该节的那些调用语句将如何解析?

【出题思路】

虚函数与其作用域的练习。

【解答】

550页的原程序如下:

#include <iostream>
#include <string>

using std::endl;
using std::cout;
using std::string;

class Base
{
public:
    virtual int fcn()
    {
        cout << "Base====================fcn()====" << endl;
        return 0;
    }
};

class D1: public Base
{
public:
    //隐藏基类的fcn(),这个fcn不是虚函数 D1继承了Base::fcn()的定义
    int fcn(int a)//形参列表与Base中的fcn不一样
    {
        cout << "D1======================fcn()==a=" << a << endl;
        return a;
    }

    virtual int f2()//是一个新的虚函灵敏,在Base中不存在
    {
        cout << "D1======================f2()=====" << endl;
        return 0;
    }
};

class D2: public D1
{
public:
    int fcn(int a)//是一个非虚函灵敏,隐藏了D1::fcn(int)
    {
        cout << "D2======================fcn(a)=a=" << a << endl;
        return a;
    }
    int fcn()//覆盖了Base的虚函数fcn
    {
        cout << "D2======================fcn()====" << endl;
        return 0;
    }
    int f2()//覆盖了D1的虚函数f2
    {
        cout << "D2======================f2()=====" << endl;
        return 0;
    }
};

int main()
{
    Base bobj;
    D1 d1Obj;
    D2 d2Obj;

    Base *bp1 = &bobj, *bp2 = &d1Obj, *bp3 = &d2Obj;
    bp1->fcn();//虚调用,将在运行时调用Base::fcn
    bp2->fcn();//虚调用,将在运行时调用Base::fcn
    bp3->fcn();//虚调用,将在运行时调用 D2::fcn
    cout << endl;

    D1 *d1p = &d1Obj;
    D2 *d2p = &d2Obj;
    //bp2->f2();//错误:Base没有名为f2的成员
    d1p->f2();//虚调用,将在运行时调用D1::f12()
    d2p->f2();//虚调用,将在运行时调用D2::f12()
    cout << endl;

    Base *p1 = &d2Obj;
    D1 *p2 = &d2Obj;
    D2 *p3 = &d2Obj;
    //p1->fcn(42);//错误:Base中没有接受一个int的fcn
    p2->fcn(42);//静态绑定,调用D1::fcn(int)
    p3->fcn(42);//静态绑定,调用D2::fcn(int);

    return 0;
}


运行结果:

 要让D1类需要覆盖它继承而来的fcn函数则将D1类的fcn函数更改为int fcn()。修改后 p2->fcn(42),和p3->fcn(42)这两条调用语句将会出错

修改代码重新运行结果如下:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值