为什么返回子对象时对象的生命周期"that is the complete object of a subobject"延长了?
Why is the lifetime of an object "that is the complete object of a subobject" extended when the subobject is returned?
我正在研究绑定到const &
时临时对象的生命周期的延长,我想了解以下情况:
#include <string>
#include <iostream>
char const * foo()
{
std::string s("tmp");
return s.c_str();
}
int main()
{
char const * const & p = foo();
// Why is the lifetime of the std::string extended in the following line,
// rather than just the lifetime of the char* itself?
std::cout << p; // This prints 'tmp' in VS2013
}
如前所述,在 Visual Studio 2013 年,代码构建没有错误并且控制台打印 tmp
.
这对我来说似乎很奇怪,因为生命周期被延长的对象是被调用函数局部对象的 子对象 ,当该函数退出时被销毁。堆栈上没有 std::string
作为 return 值,编译器在编译 main
函数时可以延长其生命周期 - 只有 char *
return 值,其生命周期可以延长,但将成为悬空指针。
但显然,寿命正在延长!
我发现最接近这个的问题在这里:Does "T const&t = C().a;" lengthen the lifetime of "a"? ...但是,在这个问题中,代码 B const& b = A().b;
引用了内部堆栈上的完整对象 A
调用函数,因此该对象可用延长其生命周期。
如前所述,在我看来,我的代码示例中应该延长其生命周期的对象是 char *
,而不是 char * points
所指向的字符串。 (也就是说,我认为 return 的值,只是 char *
的大小,本身会延长其生命周期,但它会变成一个悬空指针。)
我不明白如何在上面的示例代码中延长 std::string
的生命周期。有人可以解释为什么这满足 std::string
的生命周期延长 char const * const &
的标准,而不是仅仅延长 char *
的生命周期吗?
如何遵循对象的构造函数和析构函数
#include <string>
#include <iostream>
class string_like: public std::string {
public:
string_like(const char* str): std::string (str) {
std::cout << "string_like() : \n";
}
~string_like() {
std::cout << "~string_like(): \n";
}
};
char const * foo()
{
std::cout << "in foo(){} : \n" ;
string_like s("tmp");
std::cout << "leaving foo(){}" << "\n";
return s.c_str();
}
int main()
{
std::cout << "begin main()\n";
std::cout << "calling foo() :" << "\n";
char const * const & p = foo();
std::cout << "after calling foo() :\n";
std::cout << "still in main\n" ;
std::cout << p << "\n"; // print using g++
std::cout << "leave main()\n";
}
我通过 g++ 得到了以下输出:
begin main()
calling foo() :
in foo(){} :
string_like() :
leaving foo(){}
~string_like(): object is destroyed here
after calling foo() :
still in main
tmp
leave main()
我正在研究绑定到const &
时临时对象的生命周期的延长,我想了解以下情况:
#include <string>
#include <iostream>
char const * foo()
{
std::string s("tmp");
return s.c_str();
}
int main()
{
char const * const & p = foo();
// Why is the lifetime of the std::string extended in the following line,
// rather than just the lifetime of the char* itself?
std::cout << p; // This prints 'tmp' in VS2013
}
如前所述,在 Visual Studio 2013 年,代码构建没有错误并且控制台打印 tmp
.
这对我来说似乎很奇怪,因为生命周期被延长的对象是被调用函数局部对象的 子对象 ,当该函数退出时被销毁。堆栈上没有 std::string
作为 return 值,编译器在编译 main
函数时可以延长其生命周期 - 只有 char *
return 值,其生命周期可以延长,但将成为悬空指针。
但显然,寿命正在延长!
我发现最接近这个的问题在这里:Does "T const&t = C().a;" lengthen the lifetime of "a"? ...但是,在这个问题中,代码 B const& b = A().b;
引用了内部堆栈上的完整对象 A
调用函数,因此该对象可用延长其生命周期。
如前所述,在我看来,我的代码示例中应该延长其生命周期的对象是 char *
,而不是 char * points
所指向的字符串。 (也就是说,我认为 return 的值,只是 char *
的大小,本身会延长其生命周期,但它会变成一个悬空指针。)
我不明白如何在上面的示例代码中延长 std::string
的生命周期。有人可以解释为什么这满足 std::string
的生命周期延长 char const * const &
的标准,而不是仅仅延长 char *
的生命周期吗?
如何遵循对象的构造函数和析构函数
#include <string>
#include <iostream>
class string_like: public std::string {
public:
string_like(const char* str): std::string (str) {
std::cout << "string_like() : \n";
}
~string_like() {
std::cout << "~string_like(): \n";
}
};
char const * foo()
{
std::cout << "in foo(){} : \n" ;
string_like s("tmp");
std::cout << "leaving foo(){}" << "\n";
return s.c_str();
}
int main()
{
std::cout << "begin main()\n";
std::cout << "calling foo() :" << "\n";
char const * const & p = foo();
std::cout << "after calling foo() :\n";
std::cout << "still in main\n" ;
std::cout << p << "\n"; // print using g++
std::cout << "leave main()\n";
}
我通过 g++ 得到了以下输出:
begin main()
calling foo() :
in foo(){} :
string_like() :
leaving foo(){}
~string_like(): object is destroyed here
after calling foo() :
still in main
tmp
leave main()