转换因参数类型而异的函数指针 [英] Cast function pointers that differs by argument type
问题描述
为什么这不合法:
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);
派生
是基本
。为什么不能将其强制转换为函数参数?例如,即使不进行强制转换,我也可以轻松做到这一点:
Derived
is a Base
. Why can't it be casted in function parameter? For example, I can do this easily even without casting:
void takeBase(Base* c){};
takeBase(new Derived{});
推荐答案
它就是这样设计的。 基本
不是派生的
。类派生的 is-a 关系不可逆。
It's just designed to be that way. A Base
isn't a Derived
. The is-a relationship for class derivation can't be reversed.
函数参数的类型表示接受,而对象的类型表示适合。强制转换函数的类型会更改其接受的内容。允许函数接受最初不接受的内容是危险的。
The type of a function parameter means "accept", while the type of an object means "fit". Casting the type of a function changes what it accepts. It's dangerous to allow a function to accept whatever isn't what it originally accepts.
考虑以下代码:
class Base {};
class Derived : public Base {
public:
int t;
void useDerived() {}
};
void useDerived(Derived *d){
d->useDerived();
}
如果 Base $ c应该发生什么$ c>对象已传递?
Base b;
((void(*)(Base*))useDerived) (&b);
更糟糕的是,如果另外导出 Base
Even worse, what if another derivation of Base
is passed?
class AnotherDerived : public Base {
public:
double t;
void useDerived() {}
};
AnotherDerived ad;
((void(*)(Base*))useDerived) (&ad);
这篇关于转换因参数类型而异的函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!