返回值上的 C++ 方法链接不起作用

c++ method chaining on returned value not working

本文关键字:链接 不起作用 方法 C++ 返回值      更新时间:2023-10-16

我在很长一段时间后为opengl项目使用cpp。我面临着一个与 cpp 而不是 opengl 相关的问题。下面两个代码片段有什么区别?

// this works
std::string tmp = FileIO::read("vertex_shader");
const char *vertexShaderSource = tmp.c_str();
std::cout<< vertexShaderSource <<std::endl; //shows proper value
//but this doesn't work 
const char *vertexShaderSource = FileIO::read("vertex_shader").c_str();
std::cout<< vertexShaderSource <<std::endl; //shows garbage value
//FileIO::read() returns a string value

我有点困惑为什么第一个有效,第二个显示垃圾?我错过了什么吗?

请任何 cpp 专家启发我第二个代码片段有什么问题以及为什么它不起作用。提前感谢,

我想FileIO::read按值返回,然后FileIO::read("vertex_shader")返回一个临时std::string,该将在完整表达式后销毁。之后,vertexShaderSource变成一个悬空的指针,对它的任何取消引用都会导致 UB。即

const char *vertexShaderSource = FileIO::read("vertex_shader").c_str();
// vertexShaderSource becomes dangled from here
std::cout<< vertexShaderSource <<std::endl; // UB

如果使用命名变量tmp如第一个代码示例所示,则tmp在超出定义范围之前不会被销毁;那么代码就可以了。

假设FileIO::read()按值返回std::string,那么当你这样做时

FileIO::read("vertex_shader").c_str()

FileIO::read返回的std::string对象是临时的。调用其c_str()函数后,该对象将超出范围并被破坏,从而留下指向不再存在的字符串的指针。

取消引用此指针(在尝试打印字符串时发生)会导致未定义的行为

您遇到的问题与变量的生存期有关。 FileIO::read返回一个保存字符串的std::string

在第一种情况下,您将返回值复制到变量(实际上由于 RVO,不会进行任何复制),然后您将获得指向字符串的 char 数组的指针。因此,该指针指向的内存由tmp变量拥有。

在第二种情况下,您将检索指向由 read 函数返回的临时字符串所拥有的 char 数组的指针。这为您提供了一个由临时拥有的内存地址。该语句完成后,临时将连同它拥有的所有内存一起销毁,其中包括您检索并存储在vertexShaderSource中的指针所指向的 char 数组。