- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
下面代码中的reinterpret_cast
是否会导致未定义的行为?如果确实如此,是否可以以类型安全的方式定义 rpd?
class Base
{
public:
virtual ~Base() = default;
};
class Derived : public Base { };
int main(void)
{
Derived d;
Base* pb = &d;
Base*& rpb = pb;
Derived*& rpd = reinterpret_cast<Derived*&>(rpb);
return 0;
}
与我之前的 recent question 有点相关。这背后的背景;我正在试验一个适配器类,它应该允许包含协变指针类型的 vector 本身用作协变类型。
最佳答案
强制转换本身没有UB(请参阅[expr.reinterpret.cast]),但通过重新解释的引用(rpd
)访问引用的指针(rpb
) )的作用是:
[basic.lval](标准草案)
If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:56
56) The intent of this list is to specify those circumstances in which an object may or may not be aliased.
- (8.1) the dynamic type of the object,
不适用,动态类型是静态类型,即Base*
,而不是Derived*
,即泛左值的类型。
- (8.2) a cv-qualified version of the dynamic type of the object,
没有简历资格,并且类型仍然不匹配。
- (8.3) a type similar to the dynamic type of the object,
不适用。这是关于 cv 限定符分解的内容,请参阅 [conv.qual](抱歉,段落中的许多下标在 html 中输入很麻烦,并且是保持文本可读性所必需的)。
- (8.4) a type that is the signed or unsigned type corresponding to the dynamic type of the object,
仅与整数类型相关。
- (8.5) a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,
同上。
- (8.6) an aggregate or union type that includes one of the aforementioned types among its elements or non-static data members (including, recursively, an element or non-static data member of a subaggregate or contained union),
Derived*
既不是聚合也不是 union 。
- (8.7) a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
Derived*
不是 Base*
的基础。
- (8.8) a char, unsigned char, or std::byte type.
派生*
都不是这些。
由于没有任何异常(exception)情况适用,因此通过 Derived*
类型的泛左值访问 Base*
的行为未定义。
I am experimenting with an adapter class that should allow vectors containing covariant pointer types to be used as covariant types themselves.
您的实验将无法坚持基本的面向对象原则。
基引用与派生对象是协变的,因为您无法通过基引用对派生对象执行任何无法对派生对象本身执行的操作。
基类型的容器不能与派生类型的容器协变,因为您可以使用基类型的容器(通过“引用”容器派生的)基类型执行某些操作,而使用派生类型的容器则无法执行此操作:添加以下对象:其他派生类型。
尽管如此,如果容器是不可变的……它在概念上可能会起作用。实际上用 C++ 实现它是另一回事。
关于c++ - 以下reinterpret_cast是否会导致未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44338559/
我最近了解到 C++ 标准包含“严格的别名规则”,它禁止通过不同类型的变量引用相同的内存位置。 但是,该标准确实允许 char 类型合法地别名任何其他类型。这是否意味着 reinterpret_cas
我需要将一段代码从 C++ 转换为 VB6。 具体来说,这个: reinterpret_cast(reinterpret_cast(lParam)->hwndParent) 有人能告诉我这在 VB6
我正在编写与对齐相关的代码,如果给定的指针正确对齐,却没有标准的功能测试,这让我感到非常惊讶。 似乎互联网上的大多数代码都使用(long)ptr或 reinterpret_cast(ptr)测试对齐,
这个问题在这里已经有了答案: Why is reinterpret_cast not constexpr? (2 个答案) 关闭去年。 我遇到了以下错误: class NormalClass { p
我recently learned通过 reinterpret_casting 其地址将 POD 重新解释为不同的 POD 是未定义行为。所以我只是想知道 reinterpret_cast 的潜在用例
考虑以下程序: struct A{}; int main() { A a; A b = a; A c = reinterpret_cast(a); } 编译器 (g++14)
我recently learned通过 reinterpret_casting 其地址将 POD 重新解释为不同的 POD 是未定义行为。所以我只是想知道 reinterpret_cast 的潜在用例
它为什么会存在?在什么情况下它不会导致严格的别名违规,在哪些情况下会导致? 我的意思是,如果你在两个不兼容的类型之间进行转换,并且该转换的结果是唯一指向它在整个程序中使用的内存的指针,那么在假设没有其
这两个cast语句是一样的吗?它们产生相同的结果。 const std::int16_t i = 3; char a[ 2 ]; *reinterpret_cast(a) = i; reinterp
我已经编写了 MyString 和 MyStringConst 类。现在我需要不时地将 MyString 作为 MyStringConst 传递,因此重载强制转换运算符。这是我写的 MyString:
我有一个结构 S,它将两个类型为 T 的固定大小的数组打包在一起。 template struct S { array, 10> x1; array x2; }; 我想获取对大小为 2
如果我已将结构的成员复制到我的类中,我是否可以从我的类转换为结构? #include #include class Buffer { public: void * address;
#include struct A { int a; }; struct I1 : A { int a; }; struct I2 : A { int a; }; struct D : I1, I2
是否可以使用 reinterpret_cast 将 const 限定符仅添加到结构的一个成员。 #include std::pair test; std::pair& ctest = reinter
int main() { class_name object; object.method(); fstream file("writeobject.dat" , ios::o
当我注意到它的输出完全错误时,我正在测试一个简单的编译器。事实上,输出的字节顺序从小变大了。经过仔细检查,违规代码原来是这样的: const char *bp = reinterpret_cast(&
基本思想是创建一个可变大小的数组,在构造时固定,并在单个分配单元中创建另一个类,以减少开销并提高效率。分配缓冲区以适应数组,并使用另一个对象和新放置来构造它们。为了访问数组的元素和另一个对象,使用了指
#include struct I1 { virtual void nb1()=0; virtual ~I1(){} }; struct I2 { virtual void n
我刚刚在使用reinterpret_cast的代码中发现了一个错误,将其更改为dynamic_cast后,问题就消失了。然后,我尝试使用以下代码重现该行为: 1 #include 2 3
我想知道有没有一种不用大量复制就可以解决这个问题的好方法。 例如,假设我有一个字节缓冲区,我在其中保存了很多东西。我会正确地在其中保存 4 个字节的整数和 float 等。 现在,如果我的整数保存在缓
我是一名优秀的程序员,十分优秀!