2011-09-20 50 views
-2

我發現在編寫接受主類或子類參數的函數(使用函數重載)時,通常會發生隱式上傳(子類被升級爲主類並調用主類函數)。我不希望發生這種隱式的上傳,因爲它意味着細微的錯誤潛入並導致後來的問題。隱含的上傳問題

我已經在谷歌上搜索了這方面的信息,但是我可以利用的只有很少的連貫信息,只能間接引用它。

如何禁用,停止或防止隱式上傳(甚至是向下轉換)?

(我無法提供任何示例代碼,因爲這是不時發生的一般問題)。

不,這不是與方法(我會指定方法),但功能。

沒有示例代碼,但僞概念: void Function(BaseClass & A); void Function(SubclassClass & B);

Function(ASubclass); //Implicit upcasting occurs, calls BaseClass instead 

上述情況不會發生傳統(說是SubclassClass函數被淘汰/擦除),但子類向上轉型到BaseClass的與基類的功能使用,而是說,報告的錯誤或者產生一個警告 - 或者會有幫助,因爲我不想隱式的上傳發生。

請不要混淆upcasting與非虛擬方法調用。

+3

「我無法提供......」我敢打賭,如果您嘗試過,並且結果的質量會更高。一般問題會得到一般答案;具體問題會得到具體答案。 –

+0

顯示您的問題的代碼示例,將有助於回答這個問題 –

+1

最有可能的是,您的設計根本不正確。派生類在通過基地進行尋址時必須表現「好像」它是基類,所以這些「微妙的錯誤」可能是違反了這個承諾的結果。 –

回答

6
class Base 
{  
}; 

class Derived1:public Base 
{ 
}; 

class Derived2:private Base 
{ 
}; 

void doSomething(Base *ptr) 
{ 
} 

int main() 
{ 
    Derived1 *ptr1 = new Derived1; 
    Derived2 *ptr2 = new Derived2; 

    doSomething(ptr1); //works fine 
    doSomething(ptr2); //Gives error 

    return 0; 
}; 


上溯造型:

基類指針可以總是隻要派生類是從基類派生publically指向一個派生類對象。例如:第一個函數調用。
這個上傳發生在暗含

如果推導結果是private,則該上溯不會隱式發生,編譯器將發出錯誤。

雖然,使用private繼承是不是實現這種行爲的方式。如果它適合你的設計,你應該使用私有繼承,並且隱含地保證你不會隱式地發生上傳。

+0

非常好。我需要聽到的解決方案。如果基類在派生時受到保護,這會工作嗎? – SSight3

+0

是的,即使派生被「保護」,它也可以工作。 –

1

你說的「上鑄」是正常的。您所描述的症狀聽起來像是超負荷非虛擬父母成員函數。

例如

#include <iostream> 
using namespace std; 

struct A 
{ 
    void sayHello() {cout << "hello from A" << endl;} 
}; 

struct B : public A 
{ 
    void sayHello() {cout << "hello from B" << endl;} 
}; 

void hello(A& a) 
{ 
    a.sayHello(); 
} 

int main() 
{ 
    A a; 
    B b; 
    hello(a); 
    hello(b); 
} 

會產生

hello from A 
hello from A 

,但如果添加到virual A :: sayHello的一切工作,你會期望

struct A 
{ 
    virtual void sayHello() {cout << "hello from A" << endl;} 
}; 
+0

這不是上傳的定義。很好的嘗試,但這些都是遺傳問題。 – SSight3

0

我不是100%確定發生了什麼,但是如果在向我提供派生類對象時調用基類方法然後或者a)你沒有重寫派生類中的基類方法,或者更可能是b)在基類聲明中忘記了'virtual'關鍵字。否則派生類方法將按預期方式調用。

+0

沒有方法。只是需要基類和子類的函數。 – SSight3

0

@如果派生處於受保護模式,那麼您的示例將無法工作。僅在派生類內(派生類的方法內)允許上傳,因爲受保護成員只能在派生類或基類內部訪問。