一個含成員指針的類有多個不同的構造函數,析構函數怎麼寫?
假設一個類有個成員指針,它有兩個構造函數,一個構造函數會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++的基本語法學好,
第二句話,一個析構函數與構造函數有啥關係?析構函數只和這個對象有關係,它不管你是如何構造的,只看你構造出什麼?
推薦閱讀: