【问题标题】:Why can't we return an object by reference from a function in C++?为什么我们不能通过引用从 C++ 中的函数返回对象?
【发布时间】:2019-05-05 19:10:51
【问题描述】:

据我了解,原因是我们不必要地为 a=b; 之类的简单语句调用了复制构造函数(两者都是对象)。

我不明白的是,在我的书中写道,我们不应该通过引用传递对象,因为一旦函数终止,该引用就不再存在。

那么我书中的文字是错误的还是我在这里遗漏了什么? Text 参考:Overloading assignment operator in C++

【问题讨论】:

  • 您引用的书不完整或书有误。通过引用返回对象很好。一旦函数返回(即函数本地的对象),您不应返回对被破坏的对象的引用
  • “引用不复存在”仅适用于在该函数内创建的堆栈变量。这里*this 在函数返回后不会被销毁。
  • 如果链接后面的文字与您的问题相关,您应该将其包含在问题中。抱歉,一键离你已经很远了
  • @user463035818 我已经完全发布了相关文本。感谢您的回答。
  • 您书中的文字严重错误。买一本新书。

标签: c++ pass-by-reference assignment-operator pass-by-value


【解决方案1】:

从函数返回引用并没有错。

确实,赋值运算符 operator= 通常是这样定义的(return *this; 用于方法链接)!

你不应该做的是返回对超出范围的对象的引用,例如

int& undefinedBehaviourServer()
{
    int ub;
    return ub;
}

在这种情况下,ub 具有自动存储持续时间,并且返回的对它的引用将悬空

【讨论】:

  • return ub; 我知道你在那里做了什么
  • 对不起,我不知道什么是自动存储期限。是否可以说我们永远不应该通过引用返回函数的局部内容?
  • @ShashankKadambri:有一个谷歌:“自动存储持续时间”是“局部变量”的正式术语。这就是我小时候auto 宣布的。 (从 C++11 开始 auto 意味着完全不同的东西)。
  • @Bathsheba 非常感谢您的澄清。我搜索了这个词,但我无法理解。我会保持你的方式。
【解决方案2】:

一旦函数完成,其中声明的所有对象都将被销毁。因此,通过从函数返回链接,您可能会遇到对远程对象的调用。我们来看一个典型的例子:

// don't do that!!!
std::string& get_str()
{
    std::string s = "abc";
    return s;
}


int main()
{
    string &s = get_str();
    // "abc"-string already destoyed at this moment
    std::cout << s; // attempt to deleted string: undefined behavior
}

因此,从函数返回对本地对象的引用是危险的,因为它可能涉及访问已删除的对象(未定义的行为)。尽管在技术上返回对象(非本地)引用是可能的并且经常使用。例如:

std::string& get_s()
{
    static std::string s = "abc";
    return s;
}
int main()
{
    std::string &s = get_s();
    std::cout << s; // that's OK
}

【讨论】:

  • 嗯,好吧,还有一个挑剔:返回对(非静态)本地的引用没有“危险”。这不是可能失败或潜在错误的事情。这是完全错误的。总是。
  • @user463035818 非常感谢,Luminary Magister!但“危险”并不意味着错误;)
猜你喜欢
  • 2017-11-11
  • 1970-01-01
  • 2020-11-15
  • 2014-07-25
  • 2011-06-28
  • 2020-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多