2009-11-27 99 views
8

我在使用條件操作符獲取對象的引用時遇到了一些麻煩。我有一個類似的設置:有條件的操作符問題

class D 
{ 
    virtual void bla() = 0; 
}; 

class D1 : public D 
{ 
    void bla() {}; 
}; 

class D2 : public D 
{ 
    void bla() {}; 
}; 

class C 
{ 
public: 
    C() 
    { 
     this->d1 = new D1(); 
     this->d2 = new D2(); 
    } 

    D1& getD1() {return *d1;}; 
    D2& getD2() {return *d2;} 
private: 
    D1 *d1; 
    D2 *d2; 
}; 

int main() 
{  
    C c;  
    D& d = (rand() %2 == 0 ? c.getD1() : c.getD2());  
    return 0;  
} 

編譯時,這給了我以下錯誤:

WOpenTest.cpp: In function 'int 
main()': WOpenTest.cpp:91: error: no 
match for conditional 'operator?:' in 
'((((unsigned int)rand()) & 1u) == 0u) 
? c.C::getD1() : c.C::getD2()' 

我瞭解後的C照,這是非法++標準(as seen in this blog post),但我不不知道如何在不使用條件運算符的情況下參考D

任何想法?

回答

14

演員到D&兩個分支中:

D& d = (rand() %2 == 0 ? static_cast<D&>(c.getD1()) : static_cast<D&>(c.getD2())); 
+0

是的,這個作品完美。 – laura 2009-11-27 09:08:51

+1

您只需要其中一個演員表,這可以使表達式略顯冗長。 – 2009-11-27 19:20:20

+0

@理查德,好注意啊。對我而言,如果將演員劇集應用於兩個操作數,看起來更容易,但您當然是對的,一個演員足以讓編譯器看到另一個可以隱式轉換爲D&'。 – 2009-11-27 20:42:12

2

順便說一句,你不是真的需要使用條件運算符,

D* dptr; if(rand() %2 == 0) dptr = &c.getD1(); else dptr = &c.getD2(); 
D& d = *dptr; 

將工作太。

+0

這看起來有點浪費。這種方法對三元運算符有利嗎? – 2009-11-27 09:52:27

+0

這是真的,但我發現代碼看起來很笨重,如果你這樣做(使用引用看起來更乾淨)。 – laura 2009-11-27 09:53:32

+1

斯蒂芬,我只是迴應OP的回答「但我不知道如何在不使用三元運算符的情況下如何獲得我對D的引用」 – 2009-11-27 09:54:50

0

或者您可以將函數的返回類型更改爲Base Class。

+0

這會使用動態強制轉換使用兩個getter胡椒粉代碼的其餘部分,它不是真的解決方案 – laura 2009-11-27 09:54:13

+0

你是對的,static_cast應該工作。 – shyam 2009-11-27 12:15:46