2016-08-17 89 views
5

如果我沒有指定顯式轉換到Base **,爲什麼會出現編譯錯誤?鑄造到派生類ptr到ptr

我可以在處理派生類時使用指針指針嗎?

class Base { }; 
class Child : public Base { }; 

void SomeFunction(Base** ppoObj) {} 
void SomeFunction(Base* poObj) {} 

int main() 
{ 
    Child *c = new Child(); 

    // This passed. 
    SomeFunction(c); 
    SomeFunction((Base**)&c); 

    // CompilationError 
    SomeFunction(&c); 

    return 0; 
} 

回答

8

雖然可以隱式轉換Child*Base*,沒有隱式轉換從Child**Base**,因爲它可能被用來侵犯類型安全。試想一下:

class Base { }; 
class Child1 : public Base { }; 
class Child2 : public Base { }; 

int main() { 
    Child1 *c = new Child1(); 
    Base **cp = &c; // If this were allowed... 
    *cp = new Child2(); // ...then this could happen. (*cp is a Base*) 
} 

More information in the C++ FAQ

+0

當我使用SomeFunction((Base **)&c)時,我的程序運行良好。 運行時可能會出現哪些問題? @Wyzard –

+1

對,沒有*隱式*演員。你的顯式強制覆蓋了編譯器的類型檢查 - 就像你可以將一個Child1 *轉換爲一個Child2 *一樣,即使它們是不相關的類型。將'Child **'強制轉換爲'Base **'應該可以,只要你只指定兼容類型的指針(即不要做我在這個例子中做的)。 – Wyzard

1

爲什麼我得到一個編譯錯誤,如果我不指定鑄造Base**

因爲Child**不能隱式轉換爲Base**

我可以在處理派生類時使用指針指針嗎?

如果你的意思是「我能分配到Child**Base**類型的變量」,那麼答案是:不,你不能。

1

Child是一個派生類的Base,但Child*不是派生類的Base*

如果編譯器確實讓你的指針到指針自動轉換,你會得到下面的壞榜樣(改編自https://stackoverflow.com/a/2532428/2079934)運行:

Child *c = new Child; 
Base **bb = &c; 
*bb = new Base; 

c現在指向一個Base,而不是一個Child

+0

*「Child \ *不是基類派生類」*是真實的,因爲指針根本不是類類型:) – StoryTeller

+3

由於您鏈接到的問答是此線程被標記爲重複的完美目標考慮下一次你知道這樣的目標線程來提出一個(可能的)目標目標而不是不必要的重複目標的目標信息。 – dfri