Home > Enterprise >  How can I inspect the default copy/move constructors/assignment operators?
How can I inspect the default copy/move constructors/assignment operators?

Time:04-20

How do I find out what exactly my classes' default constructors, destructors, and copy/move constructors/assignment operators do?

I know about the rule of 0/3/5, and am wondering what the compiler is doing for me.

If it matters, I'm interested in >=C 17.

CodePudding user response:

The implicitly-defined copy constructor

... performs full member-wise copy of the object's bases and non-static members, in their initialization order, using direct initialization...

For a simple structure:

struct A
{
    int x;
    std::string y;
    double z;
};

The copy-constructor would be equivalent to:

A::A(A const& otherA)
    : x(otherA.x), y(otherA.y), z(otherA.z)
{
}

CodePudding user response:

It just calls the respective operation for every member and direct base class, nothing else.

E.g. the implicitly generated copy assignment calls copy assignment for every member.

Note that:

  • virtual bases are always initialized by the most-derived class. Any initializers for the virtual bases in the member-init-lists of any bases are ignored. Example:

    struct A
    {
        int x;
        A(int x) : x(x) {}
    };
    
    struct B : virtual A
    {
        B()
            : A(1) // This is ignored when constructing C.
        {}
    };
    
    struct C : B
    {
        C()
            : A(2) // If A is not default-constructible, removing this causes an error.
        {}
    };
    
    C c; // .x == 2
    
  • The implicitly generated default constructor has a unique property (shared by a default constructor that's explicitly =defaulted in the class body): if the object was created using empty parentheses/braces, any field that would otherwise be uninitialized is zeroed. Example:

    struct A
    {
        int x;
        // A() = default; // Has the same effect.
    };
    
    A f; // Uninitialized.
    A g{}; // Zeroed.
    A h = A{}; // Zeroed.
    A i = A(); // Zeroed.
    

    This applies to scalar types, and the effect propagates recursively through member class instances that have the same kind of default constructors.

  • Related