使用指針(和他們的陷阱)已被覆蓋,所以我會告訴你如何使用多態而不動態內存分配,可能證明我是一個甚至想到它的異端。
首先,讓我們看看使用你的原代碼,修補了所以編譯:
void foo(bool const cond) {
Base* b = 0;
if (cond) { b = new Derived1(); }
else { b = new Derived2(); }
b->func1();
delete b; // do not forget to release acquired memory
}
的正常工作假設你有一個virtual
析構函數Base
。
在一個程序員的發展的下一個合乎邏輯的步驟是使用智能指針,以避免寫delete
(delete
僅用於初學者和專家庫作家):
void foo(bool const cond) {
std::unique_ptr<Base> b;
if (cond) { b.reset(new Derived1()); }
else { b.reset(new Derived2()); }
b->func1();
}
,我們仍然需要virtual
當然,它的破壞者爲Base
。
讓我們意識到,這個功能做了兩件事情:
我們可以打破它,例如通過提取構建工作:
std::unique_ptr<Base> build(bool const cond) {
if (cond) { return { new Derived1() }; }
return { new Derived2() };
}
void foo(bool const cond) {
std::unique_ptr<Base> b = build(cond);
b->func1();
}
這是大多數人做的事情。
我要求還有另一種可能,而不是孤立的構建,我們可以隔離的實際工作:
void dowork(Base& b) { b.func1(); /* and perhaps other things */ }
void foo(bool const cond) {
std::unique_ptr<Base> b(cond ? new Derived1() : new Derived2());
work(*b);
}
,我們實際上可以把它一步:
void foo(bool const cond) {
if (cond) {
Derived1 d;
work(d);
} else {
Derived2 d;
work(d);
}
}
多態性不需要動態內存分配。
而且你知道什麼是有趣關於這個最後的例子:
- 它完美罰款沒有C++ 11移動語義
- 它不需要在
Base
有
virtual
析構函數
你可能想讓'Derived1'&2實際上是從某個東西派生出來的。 – Mat
爲什麼你的函數沒有返回類型? – bitmask
如果你要問這裏,你應該總是解釋編譯器如何抱怨。 (你也應該嘗試在谷歌中輸入錯誤,它比人類快) – Shep