“new Foo()”和“&Foo()”作为参数的区别
Difference between “new Foo()” and “&Foo()” as parameters
我有一些关于关键字 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
类型对象的指针。然而 s2
将保存指向类型 Base
的对象的指针。 s2.content
只会指向 Foo
类型的对象,直到保存方法完成执行。
如有错误请指正:
据我了解,new Foo()
创建了一个指向 Foo
类型的新对象的指针。另一方面,&Foo()
首先创建一个类型为 Foo
的新对象,然后指向它。
那么new Foo()
和&Foo()
到底有什么区别呢?显然,两者都为您提供了一个指向 Foo
.
类型的现有对象的指针
为什么 new Foo()
创建的对象在执行保存方法后仍然存在,而通过 &Foo()
创建的对象却没有?
会不会是&Foo()
创建了一个临时对象,执行save后就不存在了?如果是,我怎样才能延长通过 &Foo()
创建的对象的寿命,使其(至少)存活到 s2
被破坏?
编辑 1:
非常感谢您的快速回答!我只是在使用 Visual Studio,所以可能 &Foo()
编译是一些 Microsoft 特定的东西...
表达式 Foo()
创建一个新的 临时 对象,并且在该临时对象上使用寻址运算符 &
将导致编译器错误因为不允许像这样获取临时对象的地址(Foo()
是一个 rvalue 并且不能在这些对象上使用地址运算符)。
使用 new Foo
创建一个 non 临时对象,结果是指向该对象的指针。这个对象的生命周期是直到你明确地 delete
它。如果你不这样做 delete
那么你就会有内存泄漏。
What exactly is the difference between "new Foo()
" and "&Foo()
" then?
Obviously both give you a pointer to an existing object of type Foo.
Why does the object created by "new Foo()
" persist after execution of
the save method whereas the object created via "&Foo()
" does not?
new Foo()
new Foo();
这将创建一个 动态分配的 Foo
对象和 returns 指向该对象的指针。动态分配的对象将一直存在,直到它们被程序员明确删除:
Foo* foo = new Foo();
delete foo; // delete the object.
&Foo()
Foo();
这会使用 automatic-storage 创建一个 Foo
对象。这意味着它的生命周期,当对象被删除时,由对象所在的范围决定:
{
Foo foo{}; // foo lives in automatic storage.
} // end of scope, foo dies
在您的例子中,您正在创建一个新的 Foo
对象,并将此匿名对象的地址传递给 Storage::save
。该对象将在完整表达式结束时被销毁。这基本上意味着在 s2.save()
returns 之后你的对象将被销毁并且在 s2
中指向它的指针将悬空并且取消引用它将是未定义的行为。
If yes, how can I prolong the life of the object created via "&Foo()"
to make it live (at least) until the destruction of s2?
你不能。您可能需要一个智能指针,例如 std::unique_ptr
.
请注意,获取临时地址是非标准的,因此此代码一开始就是不合规的。您的编译器可能正在使用扩展来允许它。 MSVC 以允许这样做而闻名。
我有一些关于关键字 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
类型对象的指针。然而 s2
将保存指向类型 Base
的对象的指针。 s2.content
只会指向 Foo
类型的对象,直到保存方法完成执行。
如有错误请指正:
据我了解,new Foo()
创建了一个指向 Foo
类型的新对象的指针。另一方面,&Foo()
首先创建一个类型为 Foo
的新对象,然后指向它。
那么new Foo()
和&Foo()
到底有什么区别呢?显然,两者都为您提供了一个指向 Foo
.
为什么 new Foo()
创建的对象在执行保存方法后仍然存在,而通过 &Foo()
创建的对象却没有?
会不会是&Foo()
创建了一个临时对象,执行save后就不存在了?如果是,我怎样才能延长通过 &Foo()
创建的对象的寿命,使其(至少)存活到 s2
被破坏?
编辑 1:
非常感谢您的快速回答!我只是在使用 Visual Studio,所以可能 &Foo()
编译是一些 Microsoft 特定的东西...
表达式 Foo()
创建一个新的 临时 对象,并且在该临时对象上使用寻址运算符 &
将导致编译器错误因为不允许像这样获取临时对象的地址(Foo()
是一个 rvalue 并且不能在这些对象上使用地址运算符)。
使用 new Foo
创建一个 non 临时对象,结果是指向该对象的指针。这个对象的生命周期是直到你明确地 delete
它。如果你不这样做 delete
那么你就会有内存泄漏。
What exactly is the difference between "
new Foo()
" and "&Foo()
" then? Obviously both give you a pointer to an existing object of type Foo.Why does the object created by "
new Foo()
" persist after execution of the save method whereas the object created via "&Foo()
" does not?
new Foo()
new Foo();
这将创建一个 动态分配的 Foo
对象和 returns 指向该对象的指针。动态分配的对象将一直存在,直到它们被程序员明确删除:
Foo* foo = new Foo();
delete foo; // delete the object.
&Foo()
Foo();
这会使用 automatic-storage 创建一个 Foo
对象。这意味着它的生命周期,当对象被删除时,由对象所在的范围决定:
{
Foo foo{}; // foo lives in automatic storage.
} // end of scope, foo dies
在您的例子中,您正在创建一个新的 Foo
对象,并将此匿名对象的地址传递给 Storage::save
。该对象将在完整表达式结束时被销毁。这基本上意味着在 s2.save()
returns 之后你的对象将被销毁并且在 s2
中指向它的指针将悬空并且取消引用它将是未定义的行为。
If yes, how can I prolong the life of the object created via "&Foo()" to make it live (at least) until the destruction of s2?
你不能。您可能需要一个智能指针,例如 std::unique_ptr
.
请注意,获取临时地址是非标准的,因此此代码一开始就是不合规的。您的编译器可能正在使用扩展来允许它。 MSVC 以允许这样做而闻名。