错误:“A”是“B”的不可访问的基础

Abh*_*yal 6 c++ oop inheritance class c++11

我有一个代码如下 -

#include <iostream>
#include <string>

class A{
    int a;
    public: virtual void sayHello(){ std::cout << "Hello\n"; }
};

class B : private A{
    std::string name;
  public:
    B(std::string _n): name(_n){}
    void sayName(){std::cout << name << "says hello\n";}
    void sayHello(){sayName();}
};


int main() {
    A *ptr = new B("c++");
    ptr->sayHello();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它产生以下编译器输出 -

错误:

prog.cpp: In function 'int main()':
prog.cpp:20:22: error: 'A' is an inaccessible base of 'B'
  A *ptr = new B("c++");
                      ^
Run Code Online (Sandbox Code Playgroud)

如前所述 -这里这里这里,我知道如何解决这个问题。通过使用public继承而不是privateor protected

但是如果我真的想在基类后面隐藏一些接口,难道没有其他方法可以做到这一点吗?或者根据 c++ lang 规范不可能这样做。

eer*_*ika 5

如果您希望多态指针转换在类之外工作,那么继承必须是公共的。没有办法解决这个问题。

您可以添加一个成员函数来在类中进行多态指针转换:

class B : private A{
    // ...
public:
    A* getA() {
        return this;
    }
};
Run Code Online (Sandbox Code Playgroud)

这允许您执行此操作,同时仍然允许私有继承:

B* b_ptr = new B("c++");
A* ptr   = b_ptr->getA();
// ptr   = b_ptr; // only allowed in member functions
Run Code Online (Sandbox Code Playgroud)

我还没有遇到过一个现实世界的设计,这个技巧会很有用,但适合你自己。


附注。请记住,您应该销毁您创建的对象。也确实意识到delete ptr具有未定义的行为,除非~A是虚拟的。