【发布时间】:2021-07-23 14:51:56
【问题描述】:
在玩 c-strings 和 std::string 时,我遇到了一种奇怪的行为(我相信这只是对我很好奇,并且存在一个完全有效的 c++ 答案)。通常,当我将字符串传递给类的构造函数时,我会执行以下操作:
class Foo {
public:
Foo(const std::string& bar) bar_(bar) { }
private:
const std::string& bar_;
};
int main() {
Foo("Baz");
return 0;
}
到目前为止效果很好,我(也许是天真地?)从未质疑过这种方法。
然后最近我想实现一个简单的包含数据的类,当剥离到它的基本结构时,它看起来像这样:
#include <iostream>
#include <string>
class DataContainer {
public:
DataContainer(const std::string& name, const std::string& description)
: name_(name), description_(description) {}
auto getName() const -> std::string { return name_; }
auto getDescription() const -> std::string { return description_; }
private:
const std::string& name_;
const std::string& description_;
};
int main() {
auto dataContainer = DataContainer{"parameterName", "parameterDescription"};
auto name = dataContainer.getName();
auto description = dataContainer.getDescription();
std::cout << "name: " << name.c_str() << std::endl;
std::cout << "description: " << description.c_str() << std::endl;
}
输出是:
name: parameterName
description:
我在这里使用*.c_str(),因为这就是我在实际代码库中使用它的方式(即使用谷歌测试和EXPECT_STREQ(s1, s2)。
当我在主函数中删除 *.c_str() 时,我得到以下输出:
name: parameterName
description: tion
所以描述的原始字符串被截断,初始字符串丢失。我可以通过将类中的类型更改为:
private:
const std::string name_;
const std::string description_;
现在我得到了预期的输出
name: parameterName
description: parameterDescription
这很好,我可以使用这个解决方案,但我想了解这里发生了什么。另外,如果我将主要功能稍微更改为
int main() {
auto dataContainer = DataContainer{"parameterName", "parameterDescription"};
auto name = dataContainer.getName().c_str();
auto description = dataContainer.getDescription().c_str();
std::cout << "name: " << name << std::endl;
std::cout << "description: " << description << std::endl;
}
我如何在 DataContainer 类中存储字符串并不重要,即通过 const ref 或 value。在这两种情况下,我都会得到
name: parameterName
description:
还有关于 clang 的警告:
<source>:19:17: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl]
auto name = dataContainer.getName().c_str();
所以我猜这个问题是由 *.c_str() 本身引起的?但是,我不太明白为什么我不能通过 const ref 存储两个字符串名称和描述。谁能解释一下这个问题?
【问题讨论】:
-
您存储对临时对象的悬空引用...
-
auto getName() const -> std::stringreturn copy... 你应该这样做auto getName() const -> const std::string&。