void fun()
{
A *a = new A; //Here A is a class
} //a should be deleted in fun()'s scope
int main()
{
fun();
return 0;
}
创建的对象存在于免费存储中,main()函数无法使用。为什么要在免费商店上创建对象。是的,我们可以将对象引用传递给main函数,但我们甚至可以传递对象的副本(即使不使用new运算符创建)。那么new和delete运算符的确切用法是什么?
答案 0 :(得分:6)
简答:在运行时分配内存。
答案 1 :(得分:3)
在你的例子中,没有,并且这不是一个好习惯 使用动态分配。在对象时使用动态分配 有身份(或由于其他原因不能复制),和 对象的生命周期不对应一些 预定寿命,如静态或自动。动态 在一些复制的情况下也可以使用分配 昂贵,而剖析器显示复制是 瓶颈;在这种情况下,使用动态分配和 复制指针可能会消除瓶颈。 (但这应该 在分析显示必要之前永远不要做。)
答案 2 :(得分:1)
好问题。通常,它是不需要的 - 明确地说。当然,还有另一个答案是“在运行时分配内存”和类似的评论。但你可以用std::vector<>
,std::string
等来实现同样的效果。他们会在适当的时刻为你做幕后的所有记忆。
这是new/delete
的一个原因 - 实现某些类很有用。
您提到可以传递对象的副本。这可能有点贵,因此为了优化目的,用new/delete
替换最昂贵的副本是值得的。有一些称为“分析器”的工具可用于识别哪些副本很昂贵。
第三个原因是多态性。你可能有类似Base* ptr = (foo>7) ? new Derived1 : new Derived2(foo);
的代码,你不知道你需要什么对象,它应该如何表现。由于Derived1
和Derived2
的大小通常不相关,因此您只能在运行时知道需要多少内存。
答案 3 :(得分:0)
重要原因是stack的工作原理。它只有推送和弹出操作。在释放之后推送的所有内容之前,您无法在堆栈中释放内容。或者换句话说,如果从堆栈释放某些东西,例如函数返回时函数调用的堆栈帧,那么堆栈中它上面的所有内存也将被释放(并且你最好确保它被正确破坏,见下文)。
程序通常需要独立于堆栈存储数据。有两种方法:在编译时将内存分配为static data,或在free store, also called heap中分配。
当然可以有几个堆栈,实际上这通常也是有用的。但它是通过使用堆栈容器变量来完成的,类型为std::stack
,然后将其用作数据的额外堆栈。常见的处理器体系结构每个进程/线程只有一个“本机”堆栈,并且用于函数调用和堆栈变量,这些额外的堆栈总是独立的并由程序代码创建,只是与列表,映射等相同的简单数据结构。
关于你的问题中的代码,要指出的是,在现代C ++中,裸new
通常不受欢迎。您应该使用RAII mechansim,例如智能指针:
void fun()
{
auto a = std::unique_ptr<A>{ new A }; // C++11 syntax
// object is automatically destroyed when a goes out of scope, no leak
// note: heap should be used like this only if there's a reason, including:
// - A is big, and might conceivably overflow the stack
// - ownership of object may get moved and outlive the unique_ptr
}
您的具体问题“创建的对象存在于免费商店中,而main()函数无法使用。为什么要在免费商店中创建对象。”,嗯,在问题代码中,它不应该在免费商店中创建,没有理由。它应该只是简单的自动变量,当它超出范围时会自动被破坏。