为什么这段代码
std::string a = read_file_name();
const char* code = a.c_str();
与
不同const char* code = read_file_name().c_str();
似乎等于但结果却不同。第一个将a
的内容复制到code
,另一个没有。{
方法read_file_name()
返回一个字符串
我正在使用MSVC
答案 0 :(得分:9)
使用
std::string a = read_file_name();
const char* code = a.c_str();
您有一个对象a
,其生命周期超出了对read_file_name
的调用范围。
使用
const char* code = read_file_name().c_str();
将创建一个临时对象,您将获得指向其字符串的指针,然后该对象将被破坏,并为您留下一个悬空和无效的指针。
只要对象a
仍然存在,使用第一种情况下的指针就有效。使用第二个案例中的指针立即无效,并将导致Photon M5 Eclipse IDE packages here
答案 1 :(得分:8)
在第二种情况下,保留从临时对象中获取并指向资源的指针。在指针初始化之后,临时不再存在。然后你有一个悬空指针,如果你使用它还有未定义的行为。
如果不破坏大量代码, std::string
的界面就无法减少,因此不会发生这样的修复。但是这里有一种方法可以避免你自己的课程出现这个问题:
#include <iostream>
#include <string>
using namespace std;
class My_class
{
string value_;
public:
friend
static auto to_c_string( My_class const& o )
-> char const*
{ return o.value_.c_str(); }
explicit My_class( char const s[] ): value_{ s } {}
};
auto to_c_string( My_class const&& ) -> char const* = delete;
auto foo() -> My_class { return My_class{ "temporary" }; }
auto main()
-> int
{
My_class o{ "lvalue" };
cout << to_c_string( o ) << endl; // OK
#ifdef TEST
cout << to_c_string( foo() ) << endl; // !Nyet, rvalue.
#endif
}