简体   繁体   English

指针的reinterpret_cast指针

[英]reinterpret_cast of pointer to pointer

If I have a derived class pointer to pointer Derived** and wish to convert it to a base class pointer to pointer Base** , using static_cast<Base**>(ppd) doesn't compile, and I am forced to use reinterpret_cast<Base**> , which seems to work fine. 如果我有一个指向Derived**指针的Derived**类指针,并希望将其转换为一个指向Base**指针的基类指针,则无法使用static_cast<Base**>(ppd)编译,因此我不得不使用reinterpret_cast<Base**> ,似乎工作正常。 Is there a reason for this? 是否有一个原因? Is there any caveats I should bear in mind when doing this kind of reinterpret_cast? 在进行这种reinterpret_cast时,有什么需要注意的注意事项吗?

Below is a piece of sample code that I wrote: 以下是我编写的一段示例代码:

struct Base {
    Base(int x0) : x(x0) {}
    int x;
};

struct Derived : Base {
    Derived(int x0, int y0): Base(x0), y(y0) {}
    int y;
};

void foo(Base** ppb) {
    *ppb = new Derived(5, 7);
}

void bar(Derived** ppd) {
    foo(reinterpret_cast<Base**>(ppd));
}

int main() {
    Base* pb = new Base(3);
    cout << pb->x << endl;
    delete pb;

    foo(&pb);
    cout << pb->x << ' ' << static_cast<Derived*>(pb)->y << endl;
    delete pb;

    Derived* pd = new Derived(2,4);
    cout << pd->x << ' ' << pd->y << endl;
    delete pd;

    bar(&pd);
    cout << pd->x << ' ' << pd->y << endl;
    delete pd;
}

reinterpret_cast<Base**>(ppDerived) is well defined. reinterpret_cast<Base**>(ppDerived)定义正确。 Dereferencing the result if it js a pointer to a pointer to derived is undefined behaviour, and not something you are permitted to do. 如果对js的指针指向派生的指针,则取消对结果的引用是未定义的行为,而不是您可以执行的操作。 "It appears to work fine" is one possible symptom of UB. UB可能的症状之一是“看起来工作正常”。

What you probably want is: 您可能想要的是:

Base* foo() {
  return new Derived(5, 7);
}

Derived* bar() {
  return static_cast<Derived*>(foo());
}

That contains no UB and is logically equivalent. 它不包含UB,并且在逻辑上是等效的。

Or you can do: 或者,您可以执行以下操作:

template<class...Ts>
using sink=std::function<void(Ts...)>;

void foo(sink<Base*> ppb) {
  ppb(new Derived(5, 7));
}

void bar(sink<Derived*> ppd) {
  foo([&](Base*b){ ppd(static_cast<Derived*>(b)); });
}

or even 甚至

void foo(Base** ppb) {
  *ppb = new Derived(5, 7);
}

void bar(Derived** ppd) {
  Base*p=0;
  foo(&p);
  *ppd=static_cast<Derived*>(p);
}

You don't actually need the reinterpret_cast at all: 您实际上根本不需要reinterpret_cast

void bar(Derived** ppd) {
    Base *base;
    foo(&base);
    *ppd = static_cast<Derived*>(base);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM