为什么这个代码
std::string a = read_file_name();
const char* code = a.c_str();
Run Code Online (Sandbox Code Playgroud)
不同于
const char* code = read_file_name().c_str();
Run Code Online (Sandbox Code Playgroud)
似乎等于但结果却不同.第一个副本的内容a来code,另一个没有.该方法read_file_name()返回一个我正在使用MSVC的字符串
同
std::string a = read_file_name();
const char* code = a.c_str();
Run Code Online (Sandbox Code Playgroud)
你有一个物体,a它的寿命超出了召唤范围read_file_name.
同
const char* code = read_file_name().c_str();
Run Code Online (Sandbox Code Playgroud)
将创建一个临时对象,您将获得一个指向其字符串的指针,然后该临时对象将被破坏,并为您留下一个悬空和无效的指针.
只要对象a仍然存在,使用第一个案例中的指针就是有效的.使用第二种情况的指针立即无效,将导致未定义的行为
在第二种情况下,您将保留从临时对象中获取并指向资源的指针.在指针初始化之后,临时不再存在.然后你有一个悬空指针和未定义的行为,如果你使用它.
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
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
94 次 |
| 最近记录: |