2015-04-16 131 views
7

在閱讀關於將常量傳播包裝添加到標準庫(文檔號N4388)的提議時,我碰到了在紙:如何通過std :: unique_ptr成員調用其他類的const成員函數

#include <memory> 
#include <iostream> 

struct A 
{ 
    void bar() const 
    { 
     std::cout << "A::bar (const)" << std::endl; 
    } 

    void bar() 
    { 
     std::cout << "A::bar (non-const)" << std::endl; 
    } 
}; 

struct B 
{ 
    B() : m_ptrA(std::make_unique<A>()) {} 

    void foo() const 
    { 
     std::cout << "B::foo (const)" << std::endl; 
     m_ptrA->bar(); // calls A::bar() (non-const) 

     // const_cast<const std::unique_ptr<A>>(m_ptrA)->bar(); // how to call the A::bar() const? 
    } 

    void foo() 
    { 
     std::cout << "B::foo (non-const)" << std::endl; 
     m_ptrA->bar(); 
    } 

    std::unique_ptr<A> m_ptrA; 
}; 

int main() 
{ 
    const B const_b; 
    const_b.foo(); 
} 

,其輸出:

B :: foo的(常數)
A ::巴(非const)

我明白爲什麼會發生這種情況。即使指針是const,它指向的對象也是非const的,所以調用非const成員函數A::bar(這是本文中提議的全部要點,爲了避免這種看似尷尬的情況並傳播const通過包裝)。此外,他們說,爲了避免這種情況,一旦可以const_cast的指針m_ptrAB::foo() const,所以它調用所需的A::bar() const

我試過無數組合但坦率地說我不知道​​如何const_castunique_ptr。即,我如何通過m_ptrAB::foo() const執行A::bar() const的「正確」呼叫? (另見代碼中的評論,如果它不完全清楚我想要什麼)。

+2

'的static_cast (* PTR)。方法()' –

回答

5

您需要常量播所存儲的指針,而不是unique_ptr

const_cast<const A*>(m_ptrA.get())->bar(); 
const_cast<const A&>(*m_ptrA).bar(); 
+0

謝謝,這個作品確實如此。出於某種原因,我認爲我可以直接在智能指針上使用'const_cast',類似於'shared_ptr'的'static_pointer_cast'。但是你的解決方案可能是唯一的方法。 – vsoftco

+0

@vsoftco智能指針上的const_cast會改變智能指針的常量,但智能指針的'operator - >'和'operator *'不會保留返回對象的常量。這模仿了原始指針的行爲。如果你需要const保持指針,你可以使用[this implementation](http://stackoverflow.com/a/21065654/4538344)。 – StenSoft

相關問題