更多的細節,參見《C++語言的設計和演變》13.2.4.2和《C++程序設計語言》15.4.3。
有人暗示,這只是一條實現時的人為制造的規則。不是這樣的。事實上,要實現這種不安全的方法倒是非常容易的:在構造函數中直接調用虛擬函數,就象調用其它函數一樣。但是,這樣就意味著,任何虛擬函數都無法編寫了,因為它們需要依靠基類的固定的創建(invariants established by base classes)。這將會導致一片混亂。
有沒有“指定位置刪除”(placement delete)?
沒有,不過如果你需要的話,可以自己寫一個。
看看這個指定位置創建(placement new),它將對象放進了一系列Arena中;
class Arena {
public:
void* allocate(size_t);
void deallocate(void*);
// ...
};
void* operator new(size_t sz, Arena& a)
{
return a.allocate(sz);
}
Arena a1(some arguments);
Arena a2(some arguments);
這樣實現了之后,我們就可以這么寫:
X* p1 = new(a1) X;
Y* p2 = new(a1) Y;
Z* p3 = new(a2) Z;
// ...
但是,以后怎樣正確地銷毀這些對象呢?沒有對應于這種“placement new”的內建的“placement delete”,原因是,沒有一種通用的方法可以保證它被正確地使用。在C++的類型系統中,沒有什么東西可以讓我們確認,p1一定指向一個由Arena類型的a1分派的對象。p1可能指向任何東西分派的任何一塊地方。
然而,有時候程序員是知道的,所以這是一種方法:
template<class T> void destroy(T* p, Arena& a)
{
if (p) {
p->~T(); // explicit destructor call
a.deallocate(p);
}
}
延伸閱讀
文章來源于領測軟件測試網 http://www.kjueaiud.com/