2012-12-06 57 views
6

例如:當調用來自同一個非const版本重載成員函數時,可以刪除const限定符嗎?

struct B{}; 

struct A { 

const B& findB() const { /* some non trivial code */ } 

// B& findB() { /* the same non trivial code */ } 

B& findB() { 
     const A& a = *this; 
     const B& b = a.findB(); 
     return const_cast<B&>(b); 
    } 
}; 

的事情是我想避免重複恆定FINDB和非恆定FINDB成員函數內的相同的邏輯。

+0

看來你喜歡引用了很多。 –

+0

如果不需要,不需要使用指針或副本 – dchhetri

回答

7

是的,你可以投的對象const,調用const版本,然後把結果給非const

return const_cast<B&>(static_cast<const A*>(this)->findB()); 

虛擲const是安全的,只有當有問題的對象不是最初宣佈const。由於您在非const成員函數中,您可以知道這是情況,但它取決於實現。考慮:

class A { 
public: 

    A(int value) : value(value) {} 

    // Safe: const int -> const int& 
    const int& get() const { 
     return value; 
    } 

    // Clearly unsafe: const int -> int& 
    int& get() { 
     return const_cast<int&>(static_cast<const A*>(this)->get()); 
    } 

private: 
    const int value; 
}; 

一般來說,我的成員函數很短,所以重複是可以容忍的。您有時可以將實現歸入私有模板成員函數,並從兩個版本中調用該函數。

+2

「由於您處於非const方法,因此您知道這是事實。」你什麼意思?非''constst'方法可以很好地返回'const'對象。 –

+2

如果你有一個私人幫助函數,而且它不是一個const成員函數,那麼我怎樣才能從常量版本調用它而不去除常量?我怎麼能從常量公共成員函數中調用這個非常量的私有助手函數。它不會抱怨它的不變嗎? – dchhetri

1

我認爲,在這裏使用投是好的,但如果你一定要避免它,你可以使用一些模板魔術:

struct B 
{ 
    B(const B&) 
    { 
     std::cout << "oops I copied"; 
    } 
    B(){} 
}; 

struct A { 
public: 
    A(){} 
    A(const A&){ std::cout << "a is copied:(\n";} 
    const B& findB() const { return getter(*this); }  
    B& findB() { return getter(*this); } 

private: 
    template <typename T, typename V> 
    struct same_const 
    { 
     typedef V& type; 
    }; 

    template <typename T, typename V> 
    struct same_const<const T, V> 
    { 
     typedef const V& type; 
    }; 

    template <typename T> 
    static typename same_const<T,B>::type getter(T& t) { return t.b;} 

    B b; 

}; 

int main() 
{ 
    A a; 
    const A a_const; 
    const B& b1 = a.findB(); 
    B& b2 = a.findB(); 

    const B& b3 = a_const.findB(); 
    //B& b4 = a_const.findB(); 
} 
+0

哇,很酷的伎倆,但這是過分的,會讓事情變得更糟在我看來。 – dchhetri

+0

@ user814628,我同意,只是想讓它工作。 – Lol4t0

相關問題