[英]error: 'A' is an inaccessible base of 'B'
我的代码如下 -
#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;
}
它产生以下编译器输出 -
错误:
prog.cpp: In function 'int main()': prog.cpp:20:22: error: 'A' is an inaccessible base of 'B' A *ptr = new B("c++"); ^
如前所述 - 这里 , 这里和这里 ,我知道如何解决这个问题。 通过使用public
继承而不是private
或protected
。
但是,如果我真的想隐藏基类后面的一些接口,是不是还有其他方法可以做到这一点? 或者根据c ++ lang规范不可能这样做。
如果您希望多态指针转换在类外部工作,那么继承必须是公共的。 没有办法解决这个问题。
您可以添加在类中执行多态指针转换的成员函数:
class B : private A{
// ...
public:
A* getA() {
return this;
}
};
这允许您执行此操作,同时仍允许私有继承:
B* b_ptr = new B("c++");
A* ptr = b_ptr->getA();
// ptr = b_ptr; // only allowed in member functions
我没有遇到真正的世界设计,这个技巧会有用,但适合自己。
PS。 请记住,您应该销毁您创建的对象。 还要认识到delete ptr
具有未定义的行为,除非~A
是虚拟的。
即使我发现隐藏基类并想要将B
为A
也很奇怪,你可以使用operator A*()
。
它遵循一个最小的工作示例:
#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){}
operator A*() { return this; }
void sayName(){std::cout << name << "says hello\n";}
void sayHello(){sayName();}
};
现在您可以将其用作:
int main() {
A *ptr = *(new B("c++"));
ptr->sayHello();
return 0;
}
甚至更好:
int main() {
B b{"c++"};
A *ptr = b;
ptr->sayHello();
return 0;
}
将转换添加到A&
就像添加成员方法operator A&()
一样简单,定义为return *this;
。
这有一个难看的方式:C风格的演员阵容。 C样式转换可以转换为无法访问的基类。 这是唯一一种C样式强制转换可以执行C ++强制转换的东西的情况。 从cppreference ,当C样式转换(T) foo
尝试执行static_cast<T>(foo)
,它可以做的不仅仅是static_cast
:
[P] ointer或对派生类的引用另外允许转换为指针或引用到明确的基类(反之亦然), 即使基类是不可访问的 (也就是说,此转换会忽略私有继承说明符)。
强调补充说
因此,你可以这样做:
int main() {
A *ptr = (A *) new B("c++");
ptr->sayHello();
return 0;
}
这很丑陋,它带有铸造的所有缺点,特别是C型铸造。 但它确实有效,而且是允许的。
当你想隐藏A
是B
的基数时,这是有效的。
但是你的任务
A *ptr = new B("c++");
打破这个隐藏,因为你使用A*
。 所以c ++会生成错误,因为依赖项是隐藏的。 你可以做
B *ptr = new B("c++");
虽然。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.