转换因参数类型而异的函数指针 [英] Cast function pointers that differs by argument type

查看:67
本文介绍了转换因参数类型而异的函数指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么这不合法:

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 对象已传递?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆