再次"Most Important Const"
"Most Important Const" again
再次看到Herb Sutter的这篇文章,我开始思考为什么不应该同样适用于const指针。
下面是测试代码
const char* get()
{
std::string a("something");
return a.substr(1, a.size() - 3).c_str();
}
int main()
{
const char* str = get();
std::cout << str << std::endl;
return 0;
}
之前std string的substr
返回一个新的字符串对象。用g++ -Wall
编译也没有给我任何错误。那么,这个例子是否也显示了延长的临时行为,还是我只是幸运呢?
规则规定:
"临时绑定到const引用的生命周期一直延续到const的生命周期。"
在你的代码示例中没有引用&它与GOTW代码示例无关。您的代码只提供未定义行为。这取决于你如何看待它,你可能会认为自己是幸运的/不幸的,因为它有效。
重要提示:引用不是指针!!
不,指向const
的指针不延长临时的生命周期
只有将一个临时的引用绑定到const
时,生存期才会延长到引用本身的生存期。
{
Foo factory();
const Foo& fooRef = factory();
const Foo* fooPtr = &factory();
fooRef.doSomething(); // OK
fooPtr.doSomething(); // UB, dangling pointer.
}
可以想象,std::string很简单就像这样:
class string {
const char *str_;
string(const char *str) {
str_ = new char[strlen(str)];
strcpy(str_, str);
}
~string() {
delete[] str;
}
const char *c_str() {
return str_;
}
}
所以,从get()返回后,字符串将被销毁,你将有一个指向垃圾的指针。您可以使用valgrind或类似的工具轻松检测此错误。