垂头丧气:为什么:"A"是不可访问的"B"基数? [英] Downcast: why: ‘A’ is an inaccessible base of ‘B’?
问题描述
与该错误消息的其他示例不同,我已经有一个指向 A
的指针,并且想要检索实际的子类.
Unlike other examples of this error message i already have a pointer to A
and want to retrieve the actual child class.
这种安排是某些C ++包装的C代码的一部分,其中 A
是一些POD C结构(为什么没有动态强制转换),而 test
是C中的一些回调,调用C ++功能并检索应使用强制类型转换的正确对象.但是,为了防止C ++用户代码使C-Baseclass混乱,我希望对继承进行保护
.
This kind of arrangement is part of some C++ wrapped C code there A
is some POD C structure (whatswhy no dynamic cast) and test
is some callback in C that calls C++ functionality and to retrieve the correct object the cast should be used.
But to prevent C++ user code messing the C-Baseclass i would like to have the inheritance protected
.
MSVC不会对此抱怨,但是g ++会抱怨!?从标准的角度来看,哪一个是正确的,为什么?
MSVC does not complain about this but g++ does!? Which one is correct from the standards point of view and why?
#include <iostream>
using namespace std;
// plain C structure
struct A{
int i;
};
// some C++ Wrapper class
struct B: protected A{
A* get() { return this; }
void print(){cout << i << endl;}
};
extern "C" {
// C callback that gives it this pointer
void test(A* io_self){
auto b2 = static_cast<B*>(io_self);
b2->print();
}
}
int main()
{
B b;
test(b.get());
return 0;
}
给予:
$g++ -std=c++11 -o main *.cpp
main.cpp: In function ‘void test(A*)’:
main.cpp:21:43: error: ‘A’ is an inaccessible base of ‘B’
auto b2 = static_cast<B*>(io_self);
^
推荐答案
摘自c ++ 11 N3337草案(有点老,但这是我躺在的那个草案)5.2.9/11(static_cast):
From c++11 N3337 draft (a bit old but it's the one I have lying around) 5.2.9/11 (static_cast):
类型为"cv1 B的指针"的prvalue可以是转换为类型为指向cv2 D的指针"的prvalue,其中D是一个类如果来自B的有效标准转换,则从B衍生(第10条)存在指向D的指针"到指向B的指针"(4.10),cv2相同等于或大于cv1的cv资格,且B为D的虚拟基类或虚拟基的基类D类.
A prvalue of type "pointer to cv1 B," where B is a class type, can be converted to a prvalue of type "pointer to cv2 D," where D is a class derived (Clause 10) from B, if a valid standard conversion from "pointer to D" to "pointer to B" exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and B is neither a virtual base class of D nor a base class of a virtual base class of D.
在这种情况下,由于您使用受保护的继承,因此没有有效的标准转换从B到A./code>是非法的(使用g ++可以正确诊断).
In this case, since you use protected
inheritance there is no valid standard conversion from B
to A
so your static_cast
is illegal (g++ is correct to diagnose it).
在这种情况下,因为您要提供围绕C API的c ++包装器,所以我认为最简单的方法是坚持公共继承,并获得少量信任,使您的用户不会直接滥用C API.>如果他们已经有意识地选择使用您的C ++ API
In this case since you're providing a c++ wrapper around a C API I think the simplest approach is to just stick with public inheritance and have a small amount of trust that your users won't abuse the C API directly if they've already consciously chosen to use your C++ API
这篇关于垂头丧气:为什么:"A"是不可访问的"B"基数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!