简体   繁体   中英

C++ copy constructor called at return

error: use of deleted function 'A::A(const A&)'
 return tmp;
        ^~~

Why is the copy constructor called only when there is a virtual destructor in A ? How to avoid this?

struct B {};

struct A{
    std::unique_ptr<B> x;
    virtual ~A() = default;
};

A f() {
    A tmp;
    return tmp;
}

virtual ~A() = default; is a user declared destructor. Because of that, A no longer has a move constructor. That means return tmp; can't move tmp and since tmp is not copyable, you get a compiler error.

There are two ways you can fix this. You can add a move constructor like

struct A{
    std::unique_ptr<B> x;

    A() = default; // you have to add this since the move constructor was added
    A(A&&) = default; // defaulted move
    virtual ~A() = default;
};

or you can create a base class that has the virtual destructor and inherit from that like

struct C {
    virtual ~C() = default;
};

struct A : C {
    std::unique_ptr<B> x;
};

This works because A no longer has a user declared destructor (Yes, C does but we only care about A ) so it will still generate a move constructor in A . The important part of this is that C doesn't have a deleted move constructor, it just doesn't have one period, so trying to move it will cause a copy. That means C 's copy constructor is called in A 's implicitly generated move constructor since C(std::move(A_obj_to_move_from)) will copy as long as it doesn't have a deleted move constructor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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