Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy constructor initialization lists

Tags:

I know that if you leave a member out of an initialization list in a no-arg constructor, the default constructor of that member will be called.

Do copy constructors likewise call the copy constructor of the members, or do they also call the default constructor?

class myClass {
  private:
    someClass a;
    someOtherClass b;
  public:
    myClass() : a(DEFAULT_A) {} //implied is b()
    myClass(const myClass& mc) : a(mc.a) {} //implied is b(mc.b)??? or is it b()?
}
like image 580
Derek Avatar asked Apr 16 '09 04:04

Derek


People also ask

Does initializer list use copy constructor?

Parameterized constructor of “Type” class is called to initialize: variable(a). The arguments in the initializer list are used to copy construct “variable” directly.

How do you initialize a copy constructor?

Copy Constructor in C++ClassName (const ClassName &old_obj); Copy constructor is used to initialize the members of a newly created object by copying the members of an already existing object. Copy constructor takes a reference to an object of the same class as an argument.

What is constructor initializer list in C++?

Constructor is a special non-static member function of a class that is used to initialize objects of its class type. In the definition of a constructor of a class, member initializer list specifies the initializers for direct and virtual bases and non-static data members.

How do you initialize a list in C++?

In C++11 and above, we can use the initializer lists '{...}' to initialize a list. This won't work in C++98 as standard permits list to be initialized by the constructor, not by '{...}' .


1 Answers

Explicitly-defined copy constructors do not call copy constructors for the members.

When you enter the body of a constructor, every member of that class will be initialized. That is, once you get to { you are guaranteed that all your members have been initialized.

Unless specified, members are default-initialized in the order they appear in the class. (And if they can't be, the program is ill-formed.) So if you define your own copy constructor, it's now up to you to call any member copy constructors as desired.

Here is a small program you can copy-paste somewhere and mess around with:

#include <iostream>

class Foo {
public:
    Foo() {
        std::cout << "In Foo::Foo()" << std::endl;
    }

    Foo(const Foo& rhs) {
        std::cout << "In Foo::Foo(const Foo&)" << std::endl;
    }
};

class Bar {
public:
    Bar() {
        std::cout << "In Bar::Bar()" << std::endl;
    }

    Bar(const Bar& rhs) {
        std::cout << "In Bar::Bar(const Bar&)" << std::endl;
    }
};

class Baz {
public:
    Foo foo;
    Bar bar;

    Baz() {
        std::cout << "In Baz::Baz()" << std::endl;
    }

    Baz(const Baz& rhs) {
        std::cout << "In Baz::Baz(const Baz&)" << std::endl;
    }
};

int main() {
    Baz baz1;
    std::cout << "Copying..." << std::endl;
    Baz baz2(baz1);
}

As-is, this prints:

In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo()
In Bar::Bar()
In Baz::Baz(const Baz&)

Note that it's default-initializing the members of Baz.

By commenting out the explicit copy constructor, like:

/*
Baz(const Baz& rhs) {
    std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}
*/

The output will become this:

In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo(const Foo&)
In Bar::Bar(const Bar&)

It calls the copy-constructor on both.

And if we reintroduce Baz's copy constructor and explicitly copy a single member:

Baz(const Baz& rhs) :
    foo(rhs.foo)
{
    std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}

We get:

In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo(const Foo&)
In Bar::Bar()
In Baz::Baz(const Baz&)

As you can see, once you explicitly declare a copy-constructor you are responsible for the copying of all class members; it's your constructor now.

This applies for all constructors, including move constructors.

like image 109
GManNickG Avatar answered Sep 18 '22 02:09

GManNickG