c++ - 派生类返回分配的基类实例
问题描述
以下在 C++ 中是否合法?派生类正在分配基类并将其转换为派生类。显然,如果派生(C)有成员,任何通过返回的指针访问成员的人都会失败。但即使没有派生成员 - 这是合法的吗?UB?
struct B { int a; };
struct C : B {
static C* get() {
return static_cast<C*>(new B);
}
enum { X, Y,};
};
int main(){
C* c = C::get();
return c->X;
}
解决方案
是UB。标准摘录(强调我的):
8.2.9 静态投射 - 项目符号 11
“pointer to cv1 B”类型的纯右值,其中 B 是类类型,可以转换为“指向 cv2 D”类型的纯右值,其中 D 是从 B 派生的类,如果 cv2 是相同的 cv-qualification作为或比 cv1 更高的 cv 限定。如果 B 是 D 的虚拟基类或 D 的虚拟基类的基类,或者如果不存在从“指向 D”到“指向 B”的有效标准转换 ([conv.ptr]),则程序格式不正确。空指针值转换为目标类型的空指针值。如果“指向 cv1 B 的指针”类型的纯右值指向实际上是 D 类型对象的子对象的 B,则生成的指针指向 D 类型的封闭对象。否则,行为未定义。
推荐阅读
- asp.net - ASP.NET 将所有请求重定向到单个页面并重写 url,因此页面似乎位于根目录中
- android - 谷歌的新地方图书馆(实施'com.google.android.libraries.places:1.0.0')没有解决
- php - 安装 PHP MySQLi 扩展只创建 .ini 文件并且找不到 MySQLi.so 模块
- r - 一个条形图在条形图中放错了位置(ggplot2)
- angular - 使用 Angular 7 迭代 HTML 标签?(动态)
- google-chrome - 使用 Google Chrome Headless 模式强制执行屏幕截图分辨率
- walmart-api - 如何获取 Walmart API 的 API 密钥?似乎没有任何工作
- javascript - window.addEventListener 代码在移动设备上不起作用
- javascript - 一些图像逆时针旋转 90 度
- ruby-on-rails - 在 Rails 中初始化数据库行?