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.