纠错题--类的名字冲突与继承

本文详细解读了C++ Primer中文版第4版书中关于类成员命名冲突及访问权限限制的问题,通过实例展示了在派生类中重定义基类成员的正确做法,并探讨了访问基类protected成员的限制。文章还强调了设计派生类时避免与基类成员命名冲突的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在《C++ Primer中文版第4版》书的第499页有个习题15.23,现将其进行略微地修改,整理如下:

#include <iostream>
#include <string>

using namespace std;

struct Base {
    int foo(int) { return 0; }
protected:
    int bar;
    double foo_bar;
};

struct Derived : public Base {
    int foo(string) { return 0; };
    
    /* 
     * 原书中,此函数的名字为bar,这是个语法错误:重定义。
     * (因为同一个类中出现了两个名字相同的成员)
     */
    bool bar_fun(const Base &pb) { 
        /* 
         * 编译不通过。
         * 在Drived类中,无权访问基类Base类型的对象的protected成员。(P475, 15.2.2)
         * 建议将函数改成:bool bar_fun(const Derived &pb)
         */
        return foo_bar == pb.foo_bar; 
    }
    void foobar() { 
        bar = 1;    //本意是想给Base类中的int型bar赋值,应改为Base::bar = 1;

        /*
         * 下面这条语句为测试语句,若执行上述的bar=1语句,
         * 编译不会出错,但输出的结果是一个笑脸;
         * 若赋给bar大于127,则会出现“截断常数值”的警告。
         * (不太理解,为什么这里整形值可以成功地赋值给string类型的变量,
         * 若在main函数中写如下的代码则无法通过编译:
         * string s = 1;)
         */
        cout << bar << endl;
    }
protected:
    string bar;     //注意:Base中的int型bar将被隐藏
};

int main() {
    Derived d;

    /*
     * 编译不通过:参数类型不匹配。本意是想调用基类中的foobar成员函数,
     * 应改为d.Base::foobar(1024);
     */
    d.foo(1024);
    d.foobar();

    return 0;
}

引用此书第499页中的一句话来结束本文:设计派生类时,只要可能,最好避免与基类成员的名字冲突。

References:

《C++ Primer中文版第4版》P499

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值