1

我要讓「懶結構」在C++類,一個簡單的方法,這樣做是這樣的:如何在C++中執行惰性構造?

#include "b.hpp" // class B 

class A { 

public: 
    // invoke B() in b.hpp, this constructor do not actually do init  
    A(int v_in) : v(v_in) {} 

    void foo() { 
    if(flag == false) { 
     b = create_B_obj(); 
     flag = true; 
    } 
    } 
private: 
    B create_B_obj() { 
    // some expensive ops 
    //... 
    } 

private: 
    bool flag = false; 
    B b; 
    int v; 
}; 

但存在的問題是,B可以不包含默認構造函數(B())所以在這種情況下我該如何做'懶結構'?

順便說一句:我的項目中的類B就像一個套接字,它需要做連接或做類似綁定的調用,所以我想把這些昂貴的操作放在懶惰中。

回答

4

使用指針,最好是智能指針。

class A 
{ 
public: 
    void foo() { 
    if(pb == nullptr) { 
     pb.reset(create_B_obj()); 
    } 
    } 
private: 
    B* create_B_obj(); //or return std::unique_ptr 

private: 
    std::unique_ptr<B> pb; 
    int v; 
}; 

你可以避開動態分配,如果您使用投放新的替代,在這種情況下,你需要std::unique_ptr定製刪除:

class A 
{ 
public: 
    void foo() { 
    if(pb == nullptr) { 
     pb.reset(create_B_obj()); 
    } 
    } 
private: 
    B* create_B_obj() 
    { 
    return new (buffer) B(/* arguments */); 
    } 
private: 
    std::unique_ptr<B, PlacementNewDeleter> pb; 
    alignas(B) char buffer[sizeof(B)]; //buffer used by placement new 
    int v; 
}; 

其中PlacementNewDeleter定義爲:

struct PlacementNewDeleter 
{ 
    template<typename T> 
    void operator(T const *obj) const { obj->~T(); } 
}; 

希望有所幫助。

+1

放置新的很好的解決方案! – Geoffroy

2

如果您沒有訪問B類,那麼更簡單的方法就是使用指針。

std::unique_ptr<B> b; 

那麼如果您foo方法:

B foo() 
{ 
    if (! b) 
     b.reset(new B(/* params */)); 
     // or b.reset(create_B_obj());, which should return a pointer (may also return an unique_ptr) 
    return b; 
} 

std::unique_ptr重載operator bool和管理內存,使您不必delete

注:我改變了foo方法的返回類型,因爲它看起來更符合邏輯。