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

时间:2018-02-02 14:31:11

标签: c++

为什么这段代码

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

2 个答案:

答案 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
}