【问题标题】:Obtaining object from function by reference instead by value通过引用而不是通过值从函数中获取对象
【发布时间】:2014-06-11 03:30:07
【问题描述】:

我想知道下面的代码是否正确 - 它在这种情况下有效,但可能只是因为它的简单性。是什么让我想知道:函数(f1)按值返回对象,但在调用它的函数(f2)中,我通过引用而不是按值获取该对象。这是一个问题吗?我想知道,因为它对我来说看起来有点奇怪,但它有效,我认为它应该有效。因为对象是在 f1 的堆栈上创建的,然后(按值)返回到堆栈 f2,然后在 f1 堆栈上创建的 f2 堆栈上获得对该对象的引用。您对此有何看法?

class A {
public:
    A(){a=100; b=200;}
    int a;
    int b;
};
typedef boost::shared_ptr<A> AP;

AP get(){
    AP a = AP(new A());
    return a;
}


AP get2(){
    AP const& a = get();
    return a;
}

int main() {
    AP const& a = get2();
    std::cerr << a->a << std::endl;
    return 0;
}

【问题讨论】:

    标签: c++ function stack shared-ptr


    【解决方案1】:

    在这两种情况下

    AP const& a = get();
    

    AP const& a = get2();
    

    您将一个临时对象绑定到一个 const 引用。对象将处于活动状态,而引用将处于活动状态。所以你的代码没有问题。

    【讨论】:

    • 好的,很好:) 顺便说一句。我知道 const 与这个临时对象的生命周期无关,对吧?
    • @Michal W 您可以将临时对象与 const 引用绑定。如果您从引用中删除限定符 const,那么您将收到编译错误。
    【解决方案2】:

    这很奇怪,但很安全。

    将临时对象绑定到引用可将其生命周期延长至引用的生命周期;所以你所做的相当于创建一个局部对象变量。引用的使用增加了混淆,要求读者知道这些奇怪的规则才能理解正在发生的事情,但不会改变程序的有效性或行为。

    【讨论】:

    • 顺便说一句,这是什么时候改变的(这曾经是 ANSI C++ 之前的未定义行为)?
    • @Axel:我不知道,我从 1998 年左右才开始使用 C++,还没有研究过史前方言。在 C++98 中肯定是这样的。
    • 谢谢你的回答,但我还有一个。这种方式很奇怪,是的,但它不是比按值获取更快,因为我只创建引用而不是调用 operator= 吗?
    • @MichalW:不,在这两种情况下都会创建一个对象 - 如果变量是引用,则创建一个临时对象,如果它是一个对象,则创建变量本身。使用引用可能会更慢,因为(原则上)它需要被取消引用才能访问对象,但是一个体面的编译器应该能够撤消你混淆它的尝试并生成与它相同的代码直接访问对象时会这样做。
    猜你喜欢
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    • 2014-10-23
    • 2020-07-28
    • 2019-08-02
    相关资源
    最近更新 更多