2011-04-11 27 views
0

我一直在閱讀C++標準,並從那裏發現cv-qualifiers是成員函數函數簽名的一部分。如何使用cv-qualifier調用重載成員函數?

考慮下面的情況:

/****************************** 
* Function signature testing 
*******************************/ 
class Signature 
{ 
public: 
    void vSignature(void) 
    { 
     cout << "signature" << endl;   
    } 

    void vSignature(void) const 
    { 
     cout << "constant signature" << endl; 
    } 
}; 

typedef void (Signature::*constFunc)(void) const ; 
int main(void) 
{ 
    constFunc f = &Signature::vSignature; 
    Signature s; 
    s.vSignature(); //outputs 'signature' 
    (s.*f)();  // outputs 'constant signature' 
    return 0; 
} 

在上面的代碼,當我打電話vSignature在「普通」的方式,非const超載被調用。爲了「強制」使用const重載,我必須獲得指向vSignature函數的指針並將其轉換爲const重載。

除了上述之外,還有其他方法可以調用vSignature()const超載嗎?

回答

4

除了上述之外,還有其他方法可以調用vSignature()const超載嗎?

是的。你可以這樣做:

//first 
const Signature s; 
s.vSignature(); //calls const function 

//second 
Signature s; 
static_cast<const Signature &>(s).vSignature(); //calls const function 

//third 
void f(const Signature &s) 
{ 
     s.vSignature(); //calls const function 
} 

Signature s; 
f(s); 

的理念是:const函數被調用的const對象和const表達涉及的對象。

+0

第二個例子不應該是'const_cast (s)'? – MSalters 2011-04-11 11:28:46

+0

@MSalters:糟糕...我在那裏忘了'const'關鍵字。至於'const_cast',static_cast會做同樣的事情。 – Nawaz 2011-04-11 11:30:34

+0

也適用於非const對象,如果它是唯一的函數簽名。 – 2011-04-11 11:47:40

1

不是。在任何情況下,函數的cv限定版本都應該作爲非cv限定版本執行完全相同的事情,但應該爲了const正確性而在那裏。

+0

正是。你永遠不需要強迫這種或那種方式。 – 2011-04-11 11:08:12

0

從我所知道的const成員函數只在const對象上調用,所以如果你的對象是非const的,它會調用非const函數。

0

如果調用函數的對象被const然後期望的功能將被調用:

((const Signature&)s).vSignature(); 
+0

我會在這裏使用static_cast。即使它在這種情況下做了同樣的事情(如C風格演員),當某人決定改變's'類型時,它將防止不安全的演員陣容。 – 2011-04-11 11:29:23

0

選擇的過載依賴於表達,而不是基本的類型的對象的類型。因此,您可以添加一個強制轉換的常量:

const_cast<Signature const&>(s).vSignature(); 

這有附加的優點,讀者可以很容易地發現你在做什麼。