Cast函数指针因参数类型而异

时间:2014-11-25 16:52:00

标签: c++ casting function-pointers

为什么这不合法:

class Base
{
public:
    Base(){};
    virtual ~Base(){};
};

class Derived : public Base{};

void takeDerived(Derived * c){};

// main
void(*ptr)(Base*) = static_cast<void(*)(Base*)>(&takeDerived); // doesn't work

// but this work ok, as well as reinterpret_cast
// void(*ptr)(Base*) = (void(*)(Base*))(&takeDerived);

DerivedBase。为什么不能在功能参数中输入?例如,即使不进行强制转换,我也可以轻松完成此任务:

void takeBase(Base* c){};
takeBase(new Derived{});

2 个答案:

答案 0 :(得分:1)

它的设计就是这样。 new Vue({ el: '#app', methods: { search() { alert('search') }, }, data: { searchTerm: '' } }) 不是BaseDerived 是 - 关于类派生的关系无法逆转。

函数参数的类型表示&#34;接受&#34;,而对象的类型表示&#34; fit&#34;。转换函数的类型会改变它接受的内容。允许函数接受它最初接受的任何东西是危险的。

考虑以下代码:

class Base {};
class Derived : public Base {
    public:
    int t;
    void useDerived() {}
};

void useDerived(Derived *d){
    d->useDerived();
}

如果传递了Base个对象会发生什么?

Base b;
((void(*)(Base*))useDerived) (&b);

更糟糕的是,如果传递Base的另一个派生怎么办?

class AnotherDerived : public Base {
    public:
    double t;
    void useDerived() {}
};
AnotherDerived ad;
((void(*)(Base*))useDerived) (&ad);

答案 1 :(得分:0)

是的,但你正试图以相反的方式做到这一点。你做不到

void takeDerived(Derived *c) { }

...

Base b;
takeDerived(&b);

你试图做的函数指针会启用这些恶作剧;你可以做到

void (*ptr)(Base*) = takeDerived;
Base b;
ptr(&b); // Oops.

然后事情就会爆发,那会很糟糕。