2017-07-29 43 views
2

这是我遇到的一种奇怪的情况。我预期的指针是隐含向上转型:没有使用函数指针参数的隐式上传吗?

struct BaseClass 
{}; 

struct DerivedClass : BaseClass 
{}; 

void baseClassArgFunc(BaseClass* arg) {}   // Function taking BaseClass argument 
void derivedClassArgFunc(DerivedClass* arg) {}  // Function taking DerivedClass argument 

int main() 
{ 
    void (*pBaseFuncArg) (BaseClass*);  // Pointer to function taking BaseClass argument 
    void (*pDerivedFuncArg) (DerivedClass*); // Pointer to function taking DerivedClass argument 

    pBaseFuncArg = baseClassArgFunc;   // Assign pointer, works fine 
    pDerivedFuncArg = derivedClassArgFunc;  // Assign pointer, works fine 

    pBaseFuncArg = derivedClassArgFunc;   // A value of type void (*) (DerivedClass *arg) cannot be 
               // assigned to an entity of type void (*) (BaseClass *) 

    pDerivedFuncArg = baseClassArgFunc;   // A value of type void (*) (BaseClass *arg) cannot be 
               // assigned to an entity of type void (*) (DerivedClass *) 

    return 0; 
} 

我预计分配无效(*)(DerivedClass *)为void baseClassArgFunc(BaseClass的* ARG)是安全的。我很困惑。我想没有隐式的函数指针参数的上传吗?

+0

**是**。这里没有隐式的上传。 – iBug

+0

正确。不确定这个问题能否真正得到超越“是”的答案。你是否在寻找更多的东西? – hvd

+0

@hvd:类似'compatible_cast <>'为函数指针,成员指针和成员函数指针会很好... – Deduplicator

回答

3

改变你的类暴露的问题:

struct BaseClass 
{ 
}; 

struct DerivedClass : BaseClass 
{ 
    int a; 
}; 

然后

pBaseFuncArg = derivedClassArgFunc; 

是不安全的:

void derivedClassArgFunc(DerivedClass* arg) { arg->a = 42; } 


int main() 
{ 
    void (*pBaseFuncArg) (BaseClass*) = derivedClassArgFunc; 
    BaseClass base; 

    //derivedClassArgFunc(&base); // Doesn't compile as expected 
    pBaseFuncArg(&base);   // Would be UB, base->i won't exist 
} 
+0

是的,我试图想到哪种方式安全或不安全。我认为另一种方式是安全的,但似乎这里没有隐含的投射。 – Zebrafish