2017-07-29 92 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