从C ++中的函数返回一个对象

时间:2017-06-30 06:11:23

标签: c++ operator-overloading

我有一个小程序,我有一个全局函数重载运算符+

class Box {
    public:
        Box (int, int);
        Box (const Box&);
        ~Box ();
        int get_width() const;
        int get_length() const;
    private:
        int width;
        int length;
};

Box operator+(const Box& a, const Box& b) {
    int w, l;
    w = a.get_width() + b.get_width();
    l = a.get_length() + b.get_length();
    return Box(w, l);
}

在函数operation+中,我返回了类Box的对象,因为对象没有通过运算符new实例化,对象是在栈上分配的,不是吗?

int main (int argc, char *argv[]) {
    Box a(100, 200);
    Box b(101, 202);

    Box c = a + b;
    cout << "width: " << c.get_width() << "; length: " << c.get_length() << endl;
    return 0;
}

在我的main函数中,我尝试添加2个框a + b,并打印框c的大小。事实证明,对象c已经持久化,这意味着在执行函数operator+之后它不会从堆栈中删除。或者,对象c实际上是在堆中分配的?

我很困惑,有人可以向我解释这个吗?

2 个答案:

答案 0 :(得分:2)

基本上会创建两个 Box个对象:一个在main函数中,另一个在operator+函数中。 Box函数中的operator+对象 已复制 main函数中的对象中。然后,operator+函数中的对象被破坏,在main函数中留下对象。

现代优化编译器确实跳过了上面提到的一些步骤,最值得注意的是它只会创建一个单个对象作为其return value optimizations的一部分(只创建一个对象而不是复制任何东西都称为copy elision,这个术语迟早会在用C ++编程时与之联系。)

答案 1 :(得分:0)

关于你的代码。如果您有类似以下的功能

Box foo() {
    auto box_one = Box{};
    auto box_two = Box{};
    return box_one + box_two;
}

int main() {
    auto box = foo();
    // use box
}

foo()函数中的局部变量在函数的堆栈中开始(有关详细信息,请参见下面的最后一段),并将其复制(再次参见下文)到变量box中,该变量位于堆叠为main()

boxmain()变量的生命周期与周围范围相关,在本例中为main()的持续时间。对象在函数main()的堆栈上分配,它就是它所在的位置。

在大多数优化编译器(前C ++ 17)和C ++ 17之后的所有标准符合编译器中发生的事情是放置从Box函数返回的原始foo()变量直接它应该在被调用者的堆栈中,所以foo()的返回对象从一开始就在main()堆栈中(假设它从main()调用)此过程称为elision