繁体   English   中英

最佳做法与参考

[英]Best practices with references

仅出于好奇,教育和澄清的原因,我想问一下我使用参考和价值观的方式是否是好的做法。

理论上:

class ComplexGraphicalShape {
...
public:
    void setRasterImageURL(const QString &rasterImageURL);
    const QString &rasterImageURL() const;
...
private:
    const QString *_rasterImageURL;
};

...

void ShadowGram::setRasterImageURL(const QString &rasterImageURL) {
    safeDelete(_rasterImageURL); // handle deletion
    _rasterImageURL = new QString(rasterImageURL);
}

const QString &ShadowGram::rasterImageURL() const{
    // Question 2: Why is it a problem if I return 
              // return "www.url.com/shape_url.jpg"
    return *_rasterImageURL; // that is the right way
}

...

complexGraphicalShape().setRasterImageURL(kURLImagesToShare + imageName);
complexGraphicalShape().setRasterImageURL("www.url.com/url.jpg"); // Question 1.

我的第一个问题是,我可以使用setRasterImageURL函数调用内部创建的临时对象引用多长时间? 该变量在哪里?(如果没有记错,则在堆栈中,但是如果我使用该临时引用调用另一个函数,该怎么办?

我的第二个问题是,如果我想使用此return "www.url.com/shape_url.jpg" ,为什么在问题2部分得到警告? 那东西有点相似。 我可以使用该临时对象多长时间?

感谢您的时间来回答和解释

Q1:临时字符串存在只要与它绑定的临时引用。 那就是-只要您在setRasterImageURL()函数的“内部” setRasterImageURL() 当然-这包括所有称为“此功能内”的功能。 请注意,存储对该临时字符串的另一个引用不会延长临时对象的寿命。

complexGraphicalShape().setRasterImageURL("www.url.com/url.jpg");
// the temporary object is "destroyed" when it goes out of scope, and it's scope is just the called function

Q2:返回的问题是您使用“ C字符串”(字符数组)创建一个临时QString对象(在堆栈上,仍在函数内部)并返回对该临时对象的引用。 由于此函数返回后立即销毁了该临时对象,因此您的引用永远无效,并且引用了死对象。 另一方面,返回对成员变量的引用是可行的,因为该对象未销毁,因此只要您的主对象存在,该引用就有效。

const QString &ShadowGram::rasterImageURL() const{
    return "www.url.com/shape_url.jpg"
    // the temporary object is destroyed here, before the function returns, reference is invalid
}
  1. 临时存在,直到setRasterImageURL返回,所以您可以安全地传递对其的引用,但是您需要注意不要保存该引用供以后使用。 临时文件存储在编译器想要存储的任何位置。 该引用很可能在寄存器或堆栈中传递。

  2. 这是一个问题,因为您要返回对临时QString对象的引用,并且该对象在函数返回时被破坏。 您根本无法使用参考。

只要不存储对函数的引用“向内”(通常)是安全的,而从函数中对引用进行“向外”传递则需要您确保函数返回时所引用的对象仍然存在。

我的第一个问题是,我可以使用setRasterImageURL函数调用内部创建的临时对象引用多长时间?

它不是在函数调用内部创建的,而是在调用函数之前在调用者的堆栈上创建的,并在函数返回后销毁。

该变量在哪里?(如果没有记错,则在堆栈中,但是如果我使用该临时引用调用另一个函数,该怎么办?

是的,在堆栈上。 它被摧毁; 函数调用返回后(在“完整表达式”的末尾)。

那东西有点相似。 我可以使用该临时对象多长时间?

直到创建临时语句的完整表达式(即return语句)的末尾为止, 因此在函数甚至还没有完成 return它就超出了范围 这就是为什么您会收到警告的原因-返回的引用已绑定到一个不再存在的对象,并且永远无法安全使用。

标准中的12.2 [class.temporary]第5段涵盖了这两种情况:

—绑定到函数调用(5.2.2)中的参考参数的临时对象一直存在,直到包含该调用的完整表达式完成。
—函数返回语句(6.6.3)中临时绑定到返回值的生存期; 临时在return语句中的全表达式结束时销毁。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM