2016-10-02 32 views
0

我想了解有关upcasting(child to parent)的static_cast。这对我没有意义。我必须把一个孩子交给父母并且证明它。在网上查看一些代码并参考书籍时,这就是我所拥有的。演示static_cast和它的目的?

Mustang *myMustang = new Mustang; 
Car *myCar = new Car; 

myMustang = static_cast<Mustang*>(myCar); 

但坦率地说,它没有显示任何东西。我没有证实它甚至被铸造。我试图给Car类添加一个公共函数,并从孩子那里调用它,但是......它显然是继承的。

这也意味着我目前在这种类型的上传中没有看到目的。

我的问题是,我如何验证这个甚至铸造,这种铸造类型的目的是什么?

更新:答案有点难以遵循,因为我没有这种类型的铸造经验,虚拟功能是一个模糊的记忆。我的朋友能够帮助我。下面是代码,以防其他人有相同的问题。

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(); 
+1

除非'Mustang'是一个基类'Car',这是未定义的行为 –

+2

你是向下倾斜的,而不是向上倾斜的。 –

+0

也尝试使用可以通过派生类型重写的虚函数。 –

回答

1

在CRTP图案使用的一个示例:

#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); 
} 
0

使用的另一非平凡例子是类型擦除

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(); 
}