asmcriminal
asmcriminal

Reputation: 93

Demonstrate static_cast and purpose of it?

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

Answers (2)

skypjack
skypjack

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

Richard Hodges
Richard Hodges

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

Related Questions