在 std::make_shared 中将派生类转换为受保护的基接口时出错

问题描述

我有这个代码

#include <memory>

class SomeInterface {
public:
    virtual void VirtualMethod() {}

    virtual void PureVirtualMethod() = 0;
};

class SomeInterfaceDependent {
public:
    explicit SomeInterfaceDependent(SomeInterface* a) : a_(a) {}

private:
    SomeInterface* const a_;
};

class Implementation : protected SomeInterface {
public:
    void Init() {
        // Ok
        auto raw = new SomeInterfaceDependent(this);

        // Cannot cast 'Implementation' to its protected base class 'SomeInterface'.
        auto shared = std::make_shared<SomeInterfaceDependent>(this);

        // Ok
        SomeInterface* casted_some_interface = this;
        auto shared2 = std::make_shared<SomeInterfaceDependent>(casted_some_interface);
    }

protected:
    void PureVirtualMethod() override {}
};


int main() {
    Implementation i;
    i.Init();

    return 0;
}

C++ 标准 17,编译器 GCC。

当(和)出现错误 error: ‘SomeInterface’ is an inaccessible base of ‘Implementation’

  • SomeInterface 使用受保护的访问修饰符继承。
  • SomeInterfaceDependent 使用 std::make_shared 创建。
  • SomeInterface 隐式转换。

为什么?是 std::make_shared 错误吗?

解决方法

是 std::make_shared 错误吗?

没有

为什么?

std::make_shared 不是 Implementation 的友元,因此它无法访问其非公共基类,因此它无法隐式转换指针。

,

受保护的继承不对外部类公开。

因此,编译器无法看到实现继承自 SomeInterface,并会说它不能执行转换。