铸造成员函数指针 [英] casting member function pointer

查看:58
本文介绍了铸造成员函数指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用一个成员函数指针,该指针带有一个在其他代码中使用的基类的参数.好吧,我只是想做下面的例子.这段代码可以正常工作,但是我想知道这样的转换是否总是安全的吗?我无法在此处进行 dynamic static 投射.

I need to use a member function pointer that takes in an argument of base class that used in other code. Well, simply I want do to [something] like the example below. This code works fine, but I wonder if such cast is always safe? I cannot do dynamic or static cast here.

#include <cstdio>                                                   

class C
{                                                           
public:                                                             
        C () : c('c') {}                                            
        virtual ~C() {}                                             

        const char c;                                               
};                                                                  

class D : public C
{                                                
public:                                                             
        D () : d('d') {}                                            
        virtual ~D() {}                                             

        const char d;                                               
};                                                                  

class A 
{                                                           
public:                                                             
        A () {}                                                     
        virtual ~A() {}                                             

        void f( C& c ) { printf("%c\n",c.c); }                      
        void g( D& d ) { printf("%c %c\n",d.c,d.d); }               
};                                                                  

int main (int argc, char const* argv[])                             
{                                                                   
        void (A::*pf)( C& c ) = &A::f;                              
        void (A::*pg)( D& d ) = reinterpret_cast<void (A::*)(D&)>(&A::f);

        A a;                                                        
        C c;                                                        
        D d;                                                        

        (a.*pf)( c );                                               
        (a.*pg)( d );                                               

        return 0;                                                   
}                                                              

推荐答案

您要尝试执行的操作无法在C ++中合法完成.C ++不支持函数参数类型的任何协方差或反方差,无论这是成员函数还是自由函数.

What you are trying to do cannot be done legally in C++. C++ does not support any kind of co-variance or contra-variance on function parameter types, regardless of whether this is a member function or a free function.

在您的情况下,实现它的正确方法是为参数类型转换目的引入一个中间函数

In your situation the proper way to implement it is to introduce an intermediate function for parameter-type-conversion purposes

class A 
{                                                           
public:          
  ...                                                   
  void f( C& c ) { printf("%c\n",c.c); }                      
  void f_with_D( D& d ) { f(d); }
  ...
};          

并使您的指针指向该中间函数,而无需进行任何强制转换

and make your pointer point to that intermediate function without any casts

void (A::*pg)( D& d ) = &A::f_with_D;

现在

A a;
D d;                                                        
(a.*pg)( d );

最终将使用对象 d C 子对象作为参数调用 a.f .

will ultimately call a.f with C subobject of object d as argument.

编辑:是的,它将与函数重载一起使用(如果我正确理解了您的问题).您只需要记住,对于函数重载,为了将内部调用定向到函数的正确版本,您将必须使用显式强制转换

Yes, it will work with function overload (if I understand your question correctly). You just have to keep in mind that with function overload in order to direct the inner call to the proper version of the function you'll have to use an explicit cast

class A 
{                                                           
public:          
  ...                                                   
  void f( C& c ) { printf("%c\n",c.c); }                      
  void f( D& d ) { f(static_cast<C&>(d)); }
  ...
};          

没有强制转换,您将最终得到 A :: f(D&)递归调用自己.

Without the cast you'll end up with A::f(D&) calling itself recursively.

这篇关于铸造成员函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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