01.04 C++核心準則C.50:如果在構造過程中需要“虛行為”,使用工廠函數

C++核心準則C.50:如果在構造過程中需要“虛行為”,使用工廠函數

C.50: Use a factory function if you need "virtual behavior" during initialization
C.50:如果在構造過程中需要“虛行為”,使用工廠函數

Reason(原因)

If the state of a base class object must depend on the state of a derived part of the object, we need to use a virtual function (or equivalent) while minimizing the window of opportunity to misuse an imperfectly constructed object.

如果基類對象的狀態必須依賴對象的派生部分,我們需要使用虛函數(或等價物)以便儘量壓縮沒有完美構造完成的對象被錯誤使用的時間窗口。

Note(注意)

The return type of the factory should normally be unique_ptr by default; if some uses are shared, the caller can move the unique_ptr into a shared_ptr. However, if the factory author knows that all uses of the returned object will be shared uses, return shared_ptr and use make_shared in the body to save an allocation.

工廠的返回類型通常應該默認返回unique_prt;如果有些用法需要共享,調用者可以將unique_ptr移動到shared_ptr。然而,如果工廠的作者知道返回對象的所有的用法都是共享方式,可以返回shared_ptr並在函數體內部使用make_shared節約一次內存分配。

Example, bad(反面示例)

<code>class B {
public:
B() {
/* ... */

f(); // BAD: C.82: Don't call virtual functions in constructors and destructors
/* ... */
}

virtual void f() = 0;
};/<code>

Example(示例)

<code>class B {
protected:
class Token {};

public:
explicit B(Token) { /* ... */ } // create an imperfectly initialized object
virtual void f() = 0;

template<class>
static shared_ptr create() // interface for creating shared objects
{
auto p = make_shared(typename T::Token{});
p->post_initialize();
return p;
}

protected:
virtual void post_initialize() // called right after construction
{ /* ... */ f(); /* ... */ } // GOOD: virtual dispatch is safe
};

class D : public B { // some derived class
protected:
class Token {};

public:
explicit D(Token) : B{ B::Token{} } {}
void f() override { /* ... */ };

protected:
template<class>
friend shared_ptr B::create();
};

shared_ptr p = D::create
(); // creating a D object
/<class>
/<class>/<code>

make_shared requires that the constructor is public. By requiring a protected Token the constructor cannot be publicly called anymore, so we avoid an incompletely constructed object escaping into the wild. By providing the factory function create(), we make construction (on the free store) convenient.

make_shared要求構造函數是公開的。通過要求一個保護的令牌保證構造函數不能被公開調用,這樣我們就避免了不完全構造的對象跑到野外。通過提供一個工廠方法create(),我們使(自由存儲上的)構造過程可以便利地實施。

Note(注意)

Conventional factory functions allocate on the free store, rather than on the stack or in an enclosing object.

常規的工廠方法在自由存儲上分配對象內存,而不是在堆棧或者封閉的對象內。

原文鏈接

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c50-use-a-factory-function-if-you-need-virtual-behavior-during-initialization


覺得本文有幫助?請分享給更多人。

更多精彩文章請關注微信公眾號【面向對象思考】!

面向對象開發,面向對象思考!


分享到:


相關文章: