我理解对吗,如果我使用临时对象(如
std::move()
或 std::move(A())
)调用 std::move(int)
,它会返回对空闲内存的引用?
据我所知,如果
T&&
或 const T&
分配给右值或纯右值,它会在内存中创建一个对象并继续该对象的生命周期,同时引用不会被销毁?对引用的第二次赋值是否会延续对象的生命周期?
另外,如果我调用,例如:
int x; static_cast<int&&>(x)
,据我所知,这是一个 xvalue 语句(引用),但是对象的生命周期会发生什么?
int&& foo() {
int n = 5;
return std::move(n);
}
foo(); // can second rvalue reference continue life of object while exist ref to object?
int x = 0;
static_cast<int&&>(x); // what happens with life time of object? or
static_cast<const int&>(x);
std::move(0); // will it return free memory? or
std::move(std::string("hello, world!"));
我只是一个初学者,如果我有任何错误,如果你能纠正我,我将不胜感激。
对象的生命周期在对象创建时就确定了,此后就不再改变。 您无法对已存在的对象执行任何操作,从而导致其生命周期发生变化。
具体示例:
int&& foo() {
int n = 5;
return std::move(n);
}
foo
返回悬空引用。 当 n
返回时,foo
的生命周期结束。 由于 foo
返回对 n
的引用,并且 n
的生命周期已结束,因此对 foo
返回的引用的任何读取或写入都将导致未定义的行为。
int x = 0;
static_cast<int&&>(x);
static_cast<const int&>(x);
这些类型转换什么也不做。 即使结果被分配给另一个变量,它们也不会对
x
的生命周期产生影响。
std::move(0);
std::move(std::string("hello, world!"));
这些都返回悬空引用。
0
和 std::string("hello, world!")
都创建临时对象。 引用生命周期扩展会将它们的生命周期延长到std::move
的参数的生命周期(因为它们在创建时立即绑定到该引用),但该参数的生命周期无论如何都比临时对象的生命周期短.
您的一些困惑似乎来自 C++ 所谓的“引用生命周期扩展”功能。 然而,这并不会延长现有对象的生命周期。 它只能延长对象的生命周期当它被创建时。
如果临时对象在创建时立即绑定到引用,则该临时对象的生命周期将延长到引用的生命周期。
也就是说,参考寿命延长适用于以下所有情况:
// Here the string literal "Hello World" is converted to a to a temporary std::string
// which has its lifetime extended to the lifetime of foo
const std::string& foo = "Hello World";
// Here the return value of func is a temporary int object
// which has its lifetime extended to that of i
int func() { return 42; }
const int& i = func();
参考寿命延长不适用于在这些情况下:
// The temporary object created by the int literal 42 does not have
// its lifetime extended to that of i because it is not bound to i
// at the moment of its creation.
const int& func() { return 42; }
const int& i = func();
// The lifetime of the temporary std::string object created from the
// string literal "some string" does not get extended to the lifetime
// of f.member_ref because it is not bound to member_ref at the moment
// of its creation
struct Foo
{
const std::string& member_ref;
Foo(const std::string& s) : member_ref(s) {}
};
Foo f("some string");
std::move()
没有移动任何东西。 这只是一个类型转换。 它根本不参与内存管理。如果您的函数利用其参数是右值引用这一事实来执行不安全的操作(例如使参数无效),则编译器将保护您免于使用左值调用此类函数。 但是,如果您
想要使用左值调用这样的函数,并且知道您的变量可能会无效,则std::move()
会将其转换为右值,以便您可以调用该函数。然而,是函数,而不是
std::move
,可能使参数无效。
std::move
只是让调用这样的函数成为可能。