简体   繁体   English

防止对象复制返回

[英]Prevent object copy on return

I have this:我有这个:

struct Point
{
    size_t x;
    size_t y;
    ~Point()
    {
        std::cout << "Destro" << "\n";
    }
};

const Point& getPoint()
{
    return { 100, 120 };
}
int main()
{
    Point p = getPoint();
    std::cout << "Exit" << "\n";
}

and the result is结果是

Destro
Exit
Destro

I'm basically trying to make the getPoint method not have to copy the Point class.我基本上是想让getPoint方法不必复制Point类。 Here is what's happening so far:这是到目前为止发生的事情:

  1. Point Created点已创建
  2. Point copied to the result点复制到结果
  3. Point destroyed点被摧毁

How can I make it so that Point is only destroyed once?我怎样才能让 Point 只被销毁一次?

You need to return by value instead of reference.您需要按值返回而不是按引用返回。 Using使用

Point getPoint()
{
    return { 100, 120 };
}

Allows C++17's guaranteed copy elision to kick in which causes Point p = getPoint();允许 C++17 的保证复制省略启动,从而导致Point p = getPoint(); to act as if it was Point p{ 100, 120 };表现得好像是Point p{ 100, 120 };


Side note: Never, Never, Never, return a function local object by reference.旁注:从不,从不,从不,通过引用返回函数本地对象。 That object will be destroyed at the end of the function leaving you with a dangling reference and using that is undefined behavior.该对象将在函数结束时被销毁,留下一个悬空引用,使用它是未定义的行为。

Here's an example of what it looks like you're trying to achieve...这是一个示例,说明您正在尝试实现的目标......

#include <iostream>

struct Point {
    size_t x;
    size_t y;
    ~Point() { std::cout << "Destructor called\n"; }

    // Explicitly deleting the Copy Constructor only to illustrate a point.
    Point(const Point& other) = delete;
};

const Point makePoint(size_t a, size_t b) {
    return Point{ a, b };
}

int main() {
    Point a = makePoint(3, 5);
    std::cout << a.x << ',' << a.y << '\n';
}

Output:输出:

3,5
Destructor called

If you noticed, I explicitly deleted the Copy Constructor and left the Assignment Operator undeclared so that it will use the default.如果您注意到了,我明确删除了Copy Constructor并保留了未声明的Assignment Operator以便它使用默认值。 The struct is still using the default constructor and I didn't define a User Defined constructor.该结构仍在使用默认构造函数,我没有定义User Defined构造函数。

In makePoint() I added two parameters/arguments to the function so that the user can set any values to the Point object.makePoint()我向函数添加了两个参数/参数,以便用户可以为 Point 对象设置任何值。 The function is returning a const Type object.该函数正在返回一个const Type对象。 The return statement in the function is using:函数中的 return 语句使用:

return Point{a, b};

instead of代替

return Point(a, b);

The latter will fail to compile because there is no user-defined constructor.后者将无法编译,因为没有用户定义的构造函数。 However, the former works because I'm using brace-initialization .但是,前者有效,因为我使用的是brace-initialization This will allow construction of the object on return instead of creating a temporary on the stack frame of the function and copying that temporary as its return value.这将允许在返回时构造对象,而不是在函数的堆栈帧上创建一个临时对象并将该临时对象复制为它的返回值。 This is a form of Copy Elision.这是复制省略的一种形式。

Now, if you want to be able to copy this object, you can remove the deleted constructor and allow the class to use its default copy constructor.现在,如果您希望能够copy此对象,您可以删除deleted constructor并允许该类使用其默认的复制构造函数。 The semantics of the Copy Elision will still work. Copy Elision 的语义仍然有效。

This will have the same exact results.这将具有相同的确切结果。 I showed the explicit deletion of the Copy Constructor to initially prevent any Copying semantics.我展示了显式删除 Copy Constructor 以最初防止任何 Copying 语义。 Then explained how the code works so you can take the original above and remove the line for the deleted copy constructor and it will still work the same:然后解释了代码的工作原理,以便您可以使用上面的原始代码并删除已删除的复制构造函数的行,它仍然可以正常工作:

struct Point {
    size_t x;
    size_t y;
    ~Point() { std::cout << "Destructor called\n"; }
};

const Point makePoint(size_t a, size_t b) {
    return Point{ a, b };
}

The functionality or behind the scenes magic is happening within the function makePoint() and that it returns a const object and uses brace-initialization of the class.功能或幕后魔法发生在函数makePoint() ,它返回一个const对象并使用类的brace-initialization

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

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