假設一個類有個成員指針,它有兩個構造函數,一個構造函數會new出這個指針所指向的對象;另一個構造函數含參數,會把成員指針指向該參數地址。那麼析構函數怎麼寫?這種用法是否存在錯誤?


「另一個構造函數」除了傳指針,還得穿deleter,因為誰知道你這個指針是怎麼來的,到時候怎麼刪。

雖然理論上這麼說,但是我的gayui從來都不這麼做的,因為我認為,只要用我的類,你就必須用全局的new函數(逃


得保存額外的信息。

你要先明確這個成員的所有權:兩種構造函數是不是都使得這個類擁有了這個成員的所有權?

如果是:

那就用unique_ptr,不要用裸指針。unique_ptr自己包含了析構的邏輯,也支持custom deletor。

當然你不用也行,反正所有權都歸這個類了,你直接delete就好了——當你需要面對不同deletor的時候再修補唄。

如果不是:

至少加個flag說明這個指針要不要在析構函數里被delete。你要是不怕的話也可以改造成shared_ptr,但這樣會感染整個項目。


感覺不一定要寫析構函數?

class Foo{};

class BarThatMustTakeFooOwnership {
public:
BarThatMustTakeFooOwnership() : foo_(std::make_unique&()) {}
BarThatMustTakeFooOwnership(std::unique_ptr& foo)
: foo_(std::move(foo)) {}

private:
std::unique_ptr& foo_;
};

class BarThatDoesNotAlwaysTakeFooOwnership {
public:
BarThatDoesNotAlwaysTakeFooOwnership()
: optional_foo_owner_(std::make_unique&()),
foo_(optional_foo_owner_.get()) {}
// |foo| is owned by the caller and must outlive this object.
BarThatDoesNotAlwaysTakeFooOwnership(Foo* foo) : foo_(foo) {}

private:
// Owns |foo_| if the parameter-less constructor was called. Otherwise
// nullptr.
std::unique_ptr& optional_foo_owner_;
// Owned by |optional_foo_owner_| if the parameter-less constructor was
// called. Owned by the caller of the constructor otherwise.
Foo* foo_ = nullptr;
};


用一個私有變數標記是不是自己new的?

如果是就自己delete,不是就不管。


對於類來說,類包裝了數據,數據的生命周期跟類實例的保持一致, 可以利用unique_ptr來包裝這個類的指針成員,帶參構造函數就將該參數的所有權轉移到類成員上。這沒毛病。

如果你還要繼續在類外部保持這個參數的所有權,這個設計就會出現race condition的問題。


unique_ptr歡迎你


第一句話我想說的是先把C++的基本語法學好,

第二句話,一個析構函數與構造函數有啥關係?析構函數只和這個對象有關係,它不管你是如何構造的,只看你構造出什麼?


推薦閱讀:
相关文章