error 'xxx' is an inaccessible base of 'yyy'

探讨C++中私有继承的实际含义及可见性覆写带来的逻辑冲突,分析基类方法在子类中重写其可见性的特殊情况。

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

又发生了什么

看如下代码

class VisibilityTest
{
public:
    virtual void doIt() { std::cout << "Base\n"; }
};

class DVisibilityTest : private VisibilityTest
{
private:
    virtual void doIt() override { std::cout << "Derived\n"; }
};

GCC报错信息: 'VisibilityTest' is an inaccessible base of 'DVisibilityTest'

解释

通常我们认为'private'继承仅会改变基类成员对外部的可见性, 但是这个例子明显感觉有违常识

其实private继承的真实含义除了改变成员可见性外, 还有一个是就是继承信息的可见性. 如下

class A {};
class B : private A {}; // 这里同时意味着B继承自A的这条信息只有B知道, 其他人都不知道.

同理, protect和public继承也包含的继承信息的可见性

原来是要干什么

从代码可以看出, 原来是要测试可见性的重定义问题. 在C++中, 基类中的方法在子类中可以重写其可见性. 如下

class VisibilityTest
{
public:
    virtual void doIt() { std::cout << "Base\n"; }
};

class DVisibilityTest : public VisibilityTest
{
private:
    virtual void doIt() override { std::cout << "Derived\n"; }
};

int main(int argc, char* argv[])
{
    VisibilityTest* pVT = new DVisibilityTest();
    pVT->doIt();

    // 下面的就无法运行, 编译报错doIt是private.
    /*
    DVisibilityTest* pDVT = new DVisibilityTest();
    pDVT->doIt();
    */
    return 0;
}

将可见性修饰符反过来, 逻辑也就翻过来了, 通过基类指针多态调用就会报错, 通过子类指针编译运行通过.
但是这就引入一个思考, 我们应该这样做吗?

可见性覆写既然编译器和C++标准没有禁止, 说明这个特性完全没有问题, 有些特殊情况可以使用. 但是通常的
逻辑下, 个人认为还是不要这么做:

因为继承的通常逻辑是, 子类可以替代基类, 即基类能做的, 子类都可以做, 甚至做基类做不到的, 但是如果子类
将可见性覆写为private, 这个逻辑和我们通常的认识有冲突(只有基类能做, 子类做不了). 因此通常不做么做比较好.

当然这个可见性覆写因该还有挖掘的地方, 后续在补充吧.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值