如果您想使用多態性,您不要有如您在問題中指出的那樣使用堆。但你經常沒有別的選擇。小人爲的例子:
void doSomething(int what) {
// figure out which implementation to create
Base * b;
if(doA) {
b = new ConcreteA; // 1a
} else if(doB) {
b = new ConcreteB; // 1b
}
...
b->...; // 2
}
不能使用堆棧,因爲在那一刻,你知道該怎麼做,1a和1b,每次你從堆棧獲得存儲將被回收時範圍又離開了。你必須使用這個堆,因爲你需要一些能夠保存本地作用域的存儲。
一些圖書館宣稱他們能夠不使用堆,但仍表現爲多態。他們通常做,投放新:
void doSomething(int what) {
// allocate form *the stack*, outside the if blocks, so this
// storage lasts until the function returns
char buffer[MAX(sizeof (ConcreteA), sizeof(ConcreteB))];
if(doA) {
new (buffer) ConcreteA; // 1a
} else if(doB) {
new (buffer) ConcreteB; // 1b
}
Base *b = static_cast<Base*>(static_cast<void*>(buffer));
b->...; // 2
}
在1A和1B的新的呼叫現在使用的堆棧作爲存儲爲創建的對象上創建的緩衝區。所以,不再需要堆內存分配。這種分配形式的主要缺點是,C++目前無法判斷緩衝區是否正確對齊類型ConcreteA和ConcreteB。所以,可能是數組在2字節邊界上對齊,但需要在4字節邊界上創建對象,導致在您嘗試將這些對象創建到該緩衝區時出現未定義的行爲。
Boost.Function是使用這種放置新方法創建多態類型對象而不使用使用小緩衝區的堆分配(因此,它的作用稱爲小緩衝區優化)的庫之一。