我有一些关于关键字new
和&
在特定上下文中的区别的问题。
假设这是我的代码:
struct Base {};
struct Foo : Base {};
struct Storage
{
void save(Base * object) {}
Base * content;
};
int main()
{
Storage s1, s2;
s1.save(new Foo());
s2.save(&Foo());
}
在执行main之后,s1
将保存一个指向类型为Foo
的对象的指针。然而CCD_ 5将保持指向类型为Base
的对象的指针。s2.content
将仅指向Foo
类型的对象,直到保存方法完成执行为止。
如果我错了,请纠正我:
据我所知,new Foo()
创建了一个指向Foo
类型的新对象的指针。&Foo()
首先创建一个类型为Foo
的新对象,然后指向它
那么new Foo()
和&Foo()
到底有什么区别呢?显然,两者都为您提供了一个指向类型为Foo
的现有对象的指针。
为什么new Foo()
创建的对象在执行save方法后仍然存在,而&Foo()
创建的对象则不存在?
可能是&Foo()
创建了一个临时对象,在执行save后该对象将不存在吗?如果是,我如何延长通过&Foo()
创建的对象的寿命,使其存活(至少)直到s2
被破坏?
编辑1:非常感谢你的快速回答!我只是在使用Visual Studio,所以&Foo()
编译可能是一些特定于Microsoft的东西。。。
那么"
new Foo()
"one_answers"&Foo()
"之间到底有什么区别?显然,两者都为您提供了一个指向Foo类型的现有对象的指针。为什么"
new Foo()
"创建的对象在执行保存方法,而通过"&Foo()
"创建的对象没有?
new Foo()
new Foo();
这将创建一个动态分配的Foo
对象,并返回一个指向该对象的指针。动态分配的对象将一直存在,直到程序员明确删除它们:
Foo* foo = new Foo();
delete foo; // delete the object.
&Foo()
Foo();
这将使用自动存储创建一个Foo
对象。这意味着当对象被删除时,它的生存期由对象所在的范围决定:
{
Foo foo{}; // foo lives in automatic storage.
} // end of scope, foo dies
在您的情况下,您正在创建一个新的Foo
对象,并将此匿名对象的地址传递给Storage::save
。此对象将在完整表达式结束时销毁。这基本上意味着在s2.save()
返回后,您的对象将被销毁,并且在s2
中指向它的指针将悬空,并且取消引用它将是未定义的行为。
如果是,我如何延长通过"&Foo()"创建的对象的寿命让它活着(至少)直到s2被摧毁?
你不能。您可能想要一个智能指针,例如std::unique_ptr
。
请注意,获取临时地址是非标准的,因此此代码一开始就不符合要求。您的编译器可能正在使用一个扩展来允许它。众所周知,MSVC允许这样做。
表达式Foo()
创建一个新的临时对象,在该临时对象上使用运算符&
的地址将导致编译器错误,因为它不允许获得这样的临时对象的地址(Foo()
是右值,运算符的地址不能用于这些对象)。
使用new Foo
可以创建一个非临时对象,结果是指向该对象的指针。这个对象的寿命是直到你显式地delete
它。如果你不delete
它,那么你就会有内存泄漏。