Basically to expand Charlie's answer:
When you enter the body of a class constructor, every member of that class has to have been constructed. So when you hit {, you are guaranteed that all your members have been constructed.
And this means by calling their default constructor, unless of course you explicitly call another one.
Information / Edit
You didn't mark your edit, but I think it was the clarification on if it calls b's copy-constructor if not specified. The answer is no, it does do the default constructor, if a manual copy constructor is defined at all.
Here is a small program you can copy-paste somewhere and mess around with:
#include <iostream>
class Foo
{
public:
Foo(void)
{
std::cout << "In Foo::Foo()" << std::endl;
}
Foo(const Foo& rhs)
{
std::cout << "In Foo::Foo(const Foo&)" << std::endl;
}
};
class Bar
{
public:
Bar(void)
{
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(void)
{
std::cout << "In Baz::Baz()" << std::endl;
}
Baz(const Baz& rhs)
{
std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}
};
int main(void)
{
Baz baz1;
Baz baz2(baz1);
return 0;
}
This as-is (defined copy-constructor) prints this:
In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
In Foo::Foo()
In Bar::Bar()
In Baz::Baz(const Baz&)
So left as is, it calls default on both.
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()
In Foo::Foo(const Foo&)
In Bar::Bar(const Bar&)
That is, it calls the copy-constructor on both. So as you can see, once you explicitly declare a copy-constructor you are responsible for the copying of all class members; otherwise they will be default constructed.
To finish up, only explicitly call foo's copy-constructor, like:
Baz(const Baz& rhs) :
foo(rhs.foo)
{
std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}
And you will get this:
In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
In Foo::Foo(const Foo&)
In Bar::Bar()
In Baz::Baz(const Baz&)
So it will still only default-construct your members.
Conclusion
When explicitly defining a copy-constructor, the compiler will no longer automatically copy any members for you.