Reputation: 93
I am trying to understand static_cast in regards to upcasting(child to parent). It is not making sense to me. I have to cast a child to a parent and demonstrate it. Upon looking at some code online and referencing books this is what I have.
Mustang *myMustang = new Mustang;
Car *myCar = new Car;
myMustang = static_cast<Mustang*>(myCar);
But frankly, it does not show anything. I have no verification that it even casted. I tried to add a public function to the Car class and have it called from the child, but... it is obviously inherited.
This also implies I currently do not see a purpose in this type of upcasting.
My question is, how do I verify this even casted and what is the purpose of this typing of casting?
update: The answers were a bit hard to follow due to the fact I do not have experience with this type of casting and virtual functions are a vague memory. My friend was able to help me. Below is the code in case anyone else has the same issue.
class Car {
public:
virtual void Greeting() { cout << "I am a car." << endl; };
};
class Focus : public Car{
public:
void FocusGreeting() { cout << "Hello, I am a Ford Focus." << endl; }
};
class Mustang : public Car {
public:
virtual void Greeting() override { cout << "I am a Ford Mustang." << endl; }
};
// in main
Mustang* myMustang = new Mustang;
Car *myCar = new Car;
myCar->Greeting();
cout << "Now ";
myCar = static_cast<Car*>(myMustang);
myCar->Greeting();
Upvotes: 0
Views: 73
Reputation: 50550
Another nontrivial example of use is the type-erasure:
class S {
using FN = void(*)(void*);
template<typename T>
static void invoke(void *ptr) {
static_cast<T*>(ptr)->foo();
}
public:
template<typename T>
static S create(T *t) {
S s;
s.ptr = t;
s.f = &invoke<T>;
return s;
}
void run() {
f(ptr);
}
private:
void *ptr;
FN f;
};
struct A { void foo() {} };
struct B { void foo() {} };
int main() {
A a;
B b;
S s1 = S::create(&a);
S s2 = S::create(&b);
s1.run();
s2.run();
}
Upvotes: 0
Reputation: 69902
An example of use in the CRTP pattern:
#include <type_traits>
//
// the general concept of being able to accelerate
template<class T>
struct acceleratable
{
auto accelerate() {
static_assert(std::is_base_of<acceleratable<T>, T>::value, "");
// turn this in to a T, since we know that *this really is a T
return static_cast<T*>(this)->do_accelerate();
}
};
//
// something that implementes the concept of being able to accelerate
struct car : acceleratable<car>
{
private:
friend acceleratable<car>;
void do_accelerate()
{
// accelerate implementation here
}
};
//
// free function which accelerates anything that's acceleratable
template<class Thing>
auto accelerate(Thing& t)
{
t.accelerate();
}
int main()
{
car c;
accelerate(c);
}
Upvotes: 1