简体   繁体   中英

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. Is there a reason for this? Is there any caveats I should bear in mind when doing this kind of 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. Dereferencing the result if it js a pointer to a pointer to derived is undefined behaviour, and not something you are permitted to do. "It appears to work fine" is one possible symptom of 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.

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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