2014-04-11 59 views
1

例如,假設您想要執行工廠模式。爲什麼這樣做:爲什麼在使用函數引用時使用仿函數

class IFooFactory { 
public: 
virtual ~IFooFactory() {} 
virtual std::unique_ptr<IFoo> operator()(int bar, int baz) const = 0; 
}; 

class AFactory : public IFooFactory { 
public: 
virtual std::unique_ptr<IFoo> operator()(int bar, int baz) const override { 
    std::unique_ptr<IFoo> a(new A(bar, baz)); 
    return a; 
} 
}; 

class BFactory : public IFooFactory { 
public: 
virtual std::unique_ptr<IFoo> operator()(int bar, int baz) const override { 
    std::unique_ptr<IFoo> b(new B(bar, baz)); 
    return b; 
} 
}; 

void doStuff() { 
std::unique_ptr<IFooFactory> fooFactory(new BFactory); 
doMoreStuff(fooFactory); 
} 

時,你可以這樣做:

typedef std::unique_ptr<IFoo> (&FooFactory)(int bar, int baz); 

std::unique_ptr<IFoo> AFactory(int bar, int baz) { 
std::unique_ptr<IFoo> a(new A(bar, baz)); 
return a; 
} 

std::unique_ptr<IFoo> BFactory(int bar, int baz) { 
std::unique_ptr<IFoo> b(new B(bar, baz)); 
return b; 
} 

void doStuff() { 
doMoreStuff(BFactory); 
} 

什麼是第一個解決方案的優勢是什麼?它看起來像是令人費解的OO廢話給我。

回答

2

在您的示例中,既不使用AFactory也不使用BFactory使用本地狀態。例如創建B S可需要提供給工廠的構造和第二解決方案的其他參數將與該問題:

class BFactory : public IFooFactory { 
    int zoo; 
public: 
    BFactory(int zoo): zoo(zoo) {} 
    virtual std::unique_ptr<IFoo> operator()(int bar, int baz) const override { 
    std::unique_ptr<IFoo> b(new B(bar, baz, zoo)); 
    return b; 
    } 
}; 

如果你知道你將不再需要在工廠本地狀態,然後去爲簡單的格式更好。

+0

所以如果不需要本地狀態,那麼第二個更好? – grasevski

+1

我這麼認爲。這取決於你有多確定它將來不再需要,以及一些估計,如果你碰巧是錯的,那麼改變它的代價是什麼。例如,如果接口將被某個庫公開,供其他人使用,那麼最好使用更通用的接口。另一方面,你通常應該避免過度設計事物。通常看起來更一般的界面由於您未預期的需求變化而在開發後期仍然不足。 – NonNumeric

1

使用仿函數意味着你會打電話給一個方法對象(一些類的實際實例)上,而不是調用一個簡單的函數,它沒有上下文。這意味着調用的結果可能由對象的狀態決定。

使用方法指針也可以做到這一點,但是您必須通過方法指針調用方法的對象。

使用一個仿函數,你只需要傳遞對象,通常這個對象更具可讀性。

+0

因此,如果上下文不是必需的,那麼第二個更好? – grasevski

+1

@grasevski這不是更好,它只是不同......你可能會認爲你永遠不需要上下文,當然......但是因爲你使用的是面向對象的語言,通常鼓勵在對象上使用方法,因爲它應該讓你的代碼更加模塊化。 – Macmade

+1

@grasevski不要考慮單個用途所需的代碼量。嘗試考慮代碼的模塊性,以及將來可能需要的東西。 – Macmade

相關問題