我有一个理论上的问题比实际更多,因为我只想知道在某种情况下会发生什么,而不是什么实际情况。因此,例如,如果我创建了一个智能指针对象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