我有一個理論上的問題比實際更多,因爲我只想知道在某種情況下會發生什麼,而不是什麼實際情況。因此,例如,如果我創建了一個智能指針對象std::uniqe_ptr<City> smallville(new City);
,然後在該對象內創建對象,如Building b1; Building b2;
這些對象是否仍會在堆上創建,即使語法是用於在堆棧上創建它們的?或者使用智能指針創建更多對象會更好嗎?堆上的對象
堆上的對象
回答
讓我們看一下簡單的例子:
class B{
long b;
};
class A{
B b;
int a;
};
如果你聲明在棧上,像這樣:
A a;
對象將完全與連續字節堆棧聲明。
如果我們聲明堆上,就像這樣:
A* a = new A();
對象將完全與連續字節堆聲明。
您使用智能指針的事實不會改變此行爲,所有內容都將在堆中聲明。智能指針只能用取消分配機制包裝原始指針。
如果我們採取這一步,我會說智能指針不會改變分配機制。讓我們看看下面的例子:
class C{
int* c;
public:
C(void* buffer) : c(new (buffer) int(5)){}
};
int main(){
char stackBuffer[100];
unique_ptr<C> c = std::make_unique<C>(stackBuffer);
}
在這裏,C的構造函數獲取一些緩衝區來分配一個整數。 std :: unique_ptr沒有改變分配機制,儘管C是從堆中分配的,但仍然是從堆棧中分配的緩衝區中分配整數。
或更簡單:
class E{};
int main (void){
char buffer [100];
unique_ptr<E> c(new(buffer) E());
};
unique_ptr
只裹着通過new
運算符的指針。 new
從堆棧中的緩衝區中分配了對象。 您可能會對所有這些示例感到困惑,但答案仍然很簡單 - 智能指針會保留您提供的分配機制。像我一樣沒有任何placement new
,對象將從堆中有效地分配,而不管它是否包含內部對象。所有這些將在堆上宣佈。如果你提供不同的分配機制 - 智能指針會保留它。再次,它的全部任務是用相關的析構函數封裝原始指針,該析構函數將取消分配內存。與你所謂的「在棧上」語法(自動壽命,而不是在動態壽命堆分配對象的)宣佈
對象是圍繞它們的對象或範圍,並且它們的壽命的物理部分綁在一起。因此,如果您在堆棧中分配一個對象(函數體中的Foo foo;
),則此對象及其所有自動子對象都將位於堆棧上。
在全局範圍內聲明的對象像最大生命期自動對象(與程序本身一樣),但實際存儲在靜態內存中。
如果你在堆上分配一個對象,它的所有自動子對象也將與它一起生活在堆上。
注意:這不是C++標準的一部分(只有生命週期和範圍在那裏定義),但這在實踐中發生在「常規」實現中。
smallville在棧上,但是smallville指向的新對象在堆上。
如果b1
和b2
是City
類然後將它們放置在被分配用於City
的內存塊中的非靜態成員 - 將有任何種沒有單獨的分配。
如果b1
和b2
當地人在City
的方法之一,那麼這種情況是沒有什麼不同,任何功能,他們將被放置在堆棧上。
當然,如果Building
通過new
在其ctor中進行任何分配,那麼分配的這些對象是堆中的獨立塊。
「在棧上創建它們(建築物)的語法是什麼?」 Building b1
上下文不足。這將在周圍環境中創建對象。如果周圍的上下文是一個函數,那麼該建築物將具有函數範圍(「在堆棧上」)。如果周圍的上下文是一個類,那麼這些對象將是類成員。如果沒有周圍的環境(除了程序本身),該對象將是一個全局的並且在該程序的整個生命週期中存在。
- 1. 堆棧或堆上的對象分配
- 2. 堆棧/堆上的對象創建?
- 3. 替換堆上的對象?
- 4. C++使用對象上堆
- 5. 對象的堆棧上或堆棧上的隱藏成員?
- 6. 刪除堆上存儲數據的堆上的對象
- 7. 堆上的對象的成員變量是否也自動堆在堆上?
- 8. 堆棧上的對象意外刪除
- 9. 在堆上分配的對象
- 10. Java:更改堆上的對象引用?
- 11. enable_shared_from_this和堆棧上的對象
- 12. Python是否有靜態對象,堆棧對象和堆對象?
- 13. 大對象堆
- 14. 對象堆
- 15. 堆棧中的對象vs C++堆中的對象
- 16. 調用上的指針上刪除對非堆對象
- 17. 瞭解堆對象上下文中的堆棧
- 18. 堆上有數組對象存在
- 19. 在堆棧上處理對象破壞
- 20. 堆棧上有多少個對象?
- 21. 堆謎語中的對象
- 22. 堆棧對象的C++ shared_ptr
- 23. 在堆和堆棧上創建混合矢量對象
- 24. 堆生成2和大對象堆爬
- 25. 對象分配在堆棧或堆C++
- 26. 在堆棧上創建對象和在堆上創建對象之間有什麼區別?
- 27. 對一堆對象的迭代
- 28. 受保護的堆對象堆棧vs堆棧分配
- 29. 在堆(Java)上創建對象之後調用對象的構造函數嗎?
- 30. 在應用程序中觀察堆棧和堆上的對象的值類型
你能舉出完整的例子嗎? –
你是什麼意思的「在我創造物體的對象內」,是城市的b1和b2成員? (在這種情況下,當你創建一個「新城市」時,它們會在堆上創建)。它們是函數中的局部變量嗎? (在這種情況下,它們被創建在堆棧上,當你離開函數時消失,因此指向它們是不正確的) – BrunoLevy
@NO_NAME一個例子就是我試圖用b1和b2作爲smalliville的成員來描述的。 – jonjohnson