2014-05-03 23 views
2

我有一個類FooBar,其中包含Foo類型的成員。這種類型可以繼承,因此FooBar具有可變行爲。 Foo包含訪問器方法bar的多個過載。如何在C++中「導出」一個函數的所有重載?

class FooBar; 

class Foo{ 
    friend class FooBar; 

    virtual void bar(int barIn){ bar_ = barIn; } 
    virtual void bar(int barIn, float barScale){ bar(int(barIn * barScale)); } 
    virtual void bar(const Foo& barSource){ bar(barSource.bar_); } 
    int bar(){ return bar_; } 

    int bar_; 
}; 

class FooBar{ 
public: 
    void bar(int barIn){ foo_.bar(barIn); } 
    void bar(int barIn, float barScale){ foo_.bar(barIn, barScale); } 
    void bar(const Foo& barSource){ foo_.bar(barSource); } 
    int bar(){ return foo_.bar(); } 
private: 
    Foo& foo_; 
}; 

看起來沒那麼遠,但我覺得對於FooBar.bar訪問所有的定義那種不必要的。我知道編譯器將它們內聯,所以不應該有開銷,但方法都有相同的名稱,並且都是相互重載的。

有沒有辦法在C++「導出」(我還沒有找到一個更好的詞)的訪問器,所以調用FooBar.bar只是重定向到FooBar.foo_.bar

我有一個想法是重寫operator ->FooBar,但真正的情況下,有多個類,如Foo,這樣只會讓他們的工作之一。

+0

閱讀關於用C++切片。你的FooBar類可能不會做你想做的。 (我不認爲有任何通用的方法可以做你想要的那種「代理」。) – Mat

+0

成員'Foo foo_'應該是引用/指針。否則,所有'FooBar :: bar'方法都會簡單地調用相應的'Foo :: bar'方法,它們不會爲'Foo'的派生類表現多態。如果你嘗試從外部發送'foo_'到'FooBar',那麼發送一個派生類對象'Foo'將被分割,你將面對意想不到的行爲,很難找到錯誤。見[this](http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c)和[this](http://en.wikipedia.org/wiki/Object_slicing) – Rakib

+0

@RakibulHasan哦,我沒有想到這一點。在實際情況中,它實際上是一個'unique_ptr'。答案現在被編輯。 – iFreilicht

回答

4

你可以寫一個真正的通用轉發器:

class FooBar 
{ 
public: 
    template<typename... Args> 
    auto bar(Args&&... args) -> decltype(foo_.bar(std::forward<Args>(args)...)) 
    { 
     return foo_.bar(std::forward<Args>(args)...); 
    } 

private: 
    Foo& foo_; 
}; 

(這需要C++ 11,用C++ 14,你甚至可以離開了->decltype...部分)

+0

看起來完全像我正在尋找的東西。貨運代理是否會產生開銷? – iFreilicht

+1

@iFreilicht當它被內聯時,沒有開銷。我認爲它很可能會被內聯。 –