垂头丧气:为什么:"A"是不可访问的"B"基数? [英] Downcast: why: ‘A’ is an inaccessible base of ‘B’?

查看:75
本文介绍了垂头丧气:为什么:"A"是不可访问的"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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆