2014-01-10 20 views
4
class Foo { 
public: 
    void methodA(); 
}; 

class ManagedFoo { 
Foo fooInst; 
public: 
    void methodA() { doSomething(); fooInst.methodA();} 
}; 

現在我想讓ManagedFoo作爲模板,不僅管理任何類,而且在調用Foo的任何函數之前,首先調用doSomething。C++模板能夠從父類「轉發任何類函數」嗎?

template<typename _TyManaged> 
class Manager { 
    _TyManaged _managedInst; 
    void doSomething(); 
public: 
    /*Forward every function called by _managedInst*/ 
    /*How to write this?*/ 
}; 

我想讓它一樣,讓這兩類之間的替換,就像這樣:

Foo* foo = new Foo(); 
foo->methodA(); 

Manager<Foo> managedFoo = new Manager<Foo>(); 
managedFoo->methodA(); //Hope it call Manager::doSomething() first then call _managedInst.methodA(); 

能否C++模板11做這樣的事情?如果答案是肯定的,如何?

+0

只是想了解你想要什麼,爲什麼不使用fooInst本身?這應該是一個代表嗎? – poljpocket

+1

看看如何爲'std :: shared_ptr'實現運算符' - >',這可能足夠接近。 – woolstar

+0

對不起,我應該讓自己更清楚,我已經更新了這個問題,謝謝〜 – Rayer

回答

6

解決方案基於操作符 - >重載:

#include <iostream> 
#include <memory> 

class A { 
public: 
    void foo() { std::cout << "foo\n"; } 
    void bar() { std::cout << "bar\n"; } 
}; 

template <typename T> 
class ManagedBase { 
    std::shared_ptr<T> _inst; 
public: 
    ManagedBase(const std::shared_ptr<T> inst) : _inst(inst) { } 
    virtual ~ManagedBase() { } 

    std::shared_ptr<T> operator->() { 
     before(); 
     return this->_inst; 
    } 

    virtual void before() =0; 
}; 


template <typename T> 
class ManagedPrint : public ManagedBase<T> { 
public: 
    ManagedPrint(const std::shared_ptr<T> inst) : ManagedBase(inst) { } 

    virtual void before() { 
     std::cout << "Said: "; 
    } 
}; 


int main() { 
    auto ma = ManagedPrint<A>(std::make_shared<A>()); 
    ma->bar();  // Said: foo 
    ma->bar();  // Said: bar 
} 
+0

謝謝!覆蓋operator->似乎很棒!我會試一試〜 – Rayer

2

這可以解決您的問題。但是我仍然不確定你想要用你的Manager類做什麼。

class Foo { 
    public: 
    void methodA(); 
}; 

template<typename T> 
class ManagedFoo : public T { 
    public: 
    // some further extensions 
}; 

當然這樣你由經理從改變Foo類的語義:
它有一個

這是一個
所以我不知道這是否是真的在你的情況。

+0

對不起,我沒有讓自己清楚,我已更新的問題,但無論如何謝謝:) – Rayer

3

是這樣的?

template<typename _TyManaged> 
class Manager { 
    _TyManaged _managedInst; 
    void doSomething(); 
public: 
    _TyManaged* operator->() { 
    doSomething(); 
    return &_managedInst; 
    } 
}; 
+0

感謝您脫光!這似乎很有用,我會嘗試一下,謝謝! – Rayer

+0

也看看@AlexanderMihailov解決方案,它是相似的,但有更好的方式來擴展它。 – dalle

+0

似乎,同時發佈了這兩個答案:)另一個未解決的問題是如何在託管方法調用後調用*。它可以讓它變得容易嗎? –