2010-08-26 70 views
6

對於堆棧分配的對象調用shared_from_this怎麼樣?在基類列表中的enable_shared_from_this是派生類用戶的指示符,用於創建僅在堆上(我們只希望正確使用類的用法),或者我們可以對這些錯誤提供更強的保護?或者我不明白一些時刻?

示例代碼: enable_shared_from_this和堆棧上的對象

 
class C : public enable_shared_from_this<C> 
{ 
public: 
    shared_ptr<C> method() { shared_from_this(); } 
};

void func() { C c; shared_ptr<C> ptr = c.method(); // exception comming from shared_from_this() }

+1

你到底在問什麼?你想知道是否有辦法防止在堆棧分配的對象上調用'shared_from_this()'? – 2010-08-26 10:08:53

回答

10

因此,爲了防止這個問題,你可以讓你的contstructors私有的,只能提供創建函數返回shared_ptr的 - 這樣的對象不能在棧上分配,就像這樣:

class C : public enable_shared_from_this<C> 
{ 
public: 
    static shared_ptr<C> create() { return shared_ptr<C>(new C()); } 
    shared_ptr<C> method() { shared_from_this(); } 

private: 
    C() {...} 

    // Make operator= and C(const C&) private unimplemented 
    // so the used cant do bad things like C c(* c_ptr); 
    C& operator=(const C &); 
    C(const C &); 
}; 


void func() 
{ 
    C c; // This doesnt compile 
    shared_ptr<C> ptr = c.method(); // So you can never get this 
} 

void altfunc() 
{ 
    shared_ptr<C> c_ptr = C::create(); 
    C & c_ref = *c; 
    shared_ptr<C> ptr = c_ref.method(); // OK 
} 

如果你發現自己希望爲anoperator =您可以提供使用私有實現的拷貝構造一個克隆功能,像這樣

// This goes in class C 
shared_ptr<C> C::clone() const 
{ 
    return shared_ptr<C>(new C(*this)); 
} 

// This is how you can use it 
shared_ptr<C> c2 = c1->clone(); 
+0

我知道,如果你願意跳過一些箍來故意邪惡的話,你可能仍然可以在堆棧上分配這些內容。但恕我直言,這可以防止大多數無辜的錯誤。 – 2010-08-26 10:24:34

+0

所以我們最初將設計堆堆類......這種方法是否被廣泛使用? – cybevnm 2010-08-26 12:45:08

+0

爲什麼你需要禁用賦值操作符?分配給shared_ptr中保存的對象通常很好。它的處理方式與兩個*現有*對象之間的任何其他賦值相同 - 引用計數不會受到影響。這兩個不同的*對象在賦值之後將具有相同的內容。 – nobar 2011-02-24 04:50:03