简体   繁体   English

C++,class,一个 function 返回一个 ZA8CFDE6331BD59EB2AC96F8911C4B666

[英]C++,class, a function that returns an object

I wrote a Class called Point and want to write a function that takes 2 Points and sum them.我写了一个名为Point的 Class 并想写一个 function 需要 2 个Points并将它们相加。

why I should write it as the following:为什么我应该写如下:

Point SumPoints(Point& p1, Point& p2)
{
    Point result(p1->x + p2->x, p1->y + p2->y);
    return result;
}

won't it be more efficient to define a pointer the the result and return it?为结果定义一个指针并返回它不是更有效吗? (instead of defining a new Point 'result' and then copying it again in main) (而不是定义一个新的 Point 'result' 然后在 main 中再次复制它)

Plus, I'm a little bit confused about when the copy function is being called automatically?另外,当自动调用副本 function 时,我有点困惑? is that true that whenever I type = it will be called?每当我输入=时它都会被调用,这是真的吗?

Here, it is perfectly valid to return result by value.在这里,按值返回result是完全有效的。 Modern compilers will apply NRVO named return value optimization such that no copying is required.现代编译器将应用 NRVO命名的返回值优化,这样就不需要复制。 It would be more confusing if a pointer is returned by a sum operation.如果一个指针由 sum 操作返回,那会更加混乱。

Regarding you other question (if I got that correctly), using = does not always involve copying.关于您的其他问题(如果我理解正确的话),使用=并不总是涉及复制。 For instance, there is also a move assignment operator which simply moves an rvalue reference into an object instead of copy it.例如,还有一个移动赋值运算符,它只是将rvalue引用移动到 object 中,而不是复制它。 There are also cases where copy elision applies (same link as above) and allows to completely avoid copy and move semantics.也有应用复制省略的情况(与上面相同的链接)并允许完全避免复制和移动语义。

In the following example you can see that copying or moving is mostly omitted by the compiler ( live demo )在以下示例中,您可以看到编译器大部分都省略了复制或移动(现场演示

#include <string>
#include <iostream>
#include <iomanip>

struct Point{ 
    Point() = default;
    Point(double x, double y):x(x),y(y){}

    Point(const Point &p):x(p.x),y(p.y){
        std::cout << "copy construct" << std::endl;}

    Point(Point&& p):x(std::move(p.x)),y(std::move(p.y)){
        std::cout << "move construct" << std::endl;}

    Point& operator=(const Point& p){
        x = p.x; 
        y = p.y; 
        std::cout << "copy assign" << std::endl; 
        return *this;
    }
    Point& operator=(Point&& p){
        x = std::move(p.x); 
        y = std::move(p.y); 
        std::cout << "move assign" << std::endl; 
        return *this;
    }
    double x,y;
};

std::ostream& operator<<(std::ostream& out, const Point& p)
{
    out << std::setw(5) << p.x << std::setw(5) << p.x << std::flush;
    return out;
}

Point operator+(const Point& p1, const Point &p2)
{
    return Point(p1.x+p2.x,p1.y+p2.y);
}

Point sum1(const Point& p1, const Point &p2)
{
    return Point(p1.x+p2.x,p1.y+p2.y);
}

Point sum2(const Point& p1, const Point &p2)
{
    Point result;
    result.x = p1.x+p2.x;
    result.y = p1.y+p2.y;
    return result;
}

int main()
{
    Point p1(1,0), p2(0,1);
    auto r1 = sum2(p1,p2);
    auto r2 = sum1(p1,p2);
    auto r3 = r1+r2; 
    auto r4 = r3; // <- only this calls the copy constructor

    std::cout << "r3 = ("<< r3 << ")"<< std::endl;
}

This prints:这打印:

copy construct
r3 = (    2    2)

As a hint, you can overload the + operator as shown in the example to write the summation in a more readable way.作为提示,您可以重载+运算符,如示例中所示,以更易读的方式编写总和。

won't it be more efficient to define a pointer the the result and return it?为结果定义一个指针并返回它不是更有效吗?

If you don't create an object, then there wouldn't be anything for the pointer to point to.如果您不创建 object,那么指针将不会指向任何内容。

It would also be highly confusing and un-conventional to return a pointer from addition operator.从加法运算符返回指针也将是高度混乱和非常规的。

and then copying it again in main然后在 main 中再次复制它

It won't necessarily be copied at all if the optimiser manages to elide the copy.如果优化器设法省略了副本,它就不一定会被复制。

If you're initialising an object with the result rather than assigning, you can make sure that there won't be a copy by returning a prvalue:如果您使用结果而不是分配来初始化 object,则可以通过返回纯右值来确保不会有副本:

return Point(p1->x + p2->x, p1->y + p2->y);

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

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