这两个代码似乎相同但不同

Kil*_*zor -1 c++

为什么这个代码

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)

似乎等于但结果却不同.第一个副本的内容acode,另一个没有.该方法read_file_name()返回一个我正在使用MSVC的字符串

Som*_*ude 9

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仍然存在,使用第一个案例中的指针就是有效的.使用第二种情况的指针立即无效,将导致未定义的行为


Che*_*Alf 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
}
Run Code Online (Sandbox Code Playgroud)