再次"Most Important Const"

"Most Important Const" again

本文关键字:Const Important Most 再次      更新时间:2023-10-16

再次看到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或类似的工具轻松检测此错误。