Does this mean if you have the following classes:
class B
{
private:
A a;
public:
B(const & rhs){}
}
Then the member 'a' would be left unitialised, even though it is a
UDT?
First off, your code has no semicolon after the definition of 'B' and
the argument in B's c-tor has no type. If that's fixed, then the rule
is simple: any data member omitted from the initialiser list, shall be
value-initialised ([class.base.init]/3), not *un*initialised. UDT or
not does not matter. Value-initialisation is performed differently for
POD than for non-POD, but that does not change the fact that an omitted
member is value-initialised.
V
--
I might be reading an old copy of the standard, but the version I'm
reading (
http://www.kuzbass.ru:8086/docs/isocpp) states:
class.base.init/3:
"The expression-list in a mem-initializer is used to initialize the
base class or nonstatic data member subobject denoted by the mem-
initializer-id. The semantics of a mem-initializer are as follows:
* if the expression-list of the mem-initializer is omitted, the
base class or member subobject is default-initialized (see dcl.init);
* otherwise, the subobject indicated by mem-initializer-id is
direct-initialized using expression-list as the initializer (see
dcl.init). "
So this means that:
class Bar
{
public:
~Bar() {}; // so that Bar is not POD
};
class Foo
{
private:
int x;
Bar bar;
public:
Foo();
~Foo() {};
};
Foo::Foo():
x(), // default initialised
bar() // default initialised
{}
class.base.init/4 states that:
"-4- If a given nonstatic data member or base class is not named by a
mem-initializer-id (including the case where there is no mem-
initializer-list because the constructor has no ctor-initializer),
then
* If the entity is a nonstatic data member of (possibly cv-
qualified) class type (or array thereof) or a base class, and the
entity class is a non-POD class, the entity is default-initialized
(dcl.init). If the entity is a nonstatic data member of a const-
qualified type, the entity class shall have a user-declared default
constructor.
* Otherwise, the entity is not initialized. If the entity is of
const-qualified type or reference type, or of a (possibly cv-
qualified) POD class type (or array thereof) containing (directly or
indirectly) a member of a const-qualified type, the program is ill-
formed. "
This means that if we changed the above Foo constructor to:
Foo::Foo() {};
Then Foo::bar would be default initialised whereas Foo::x would be
left uninitialised
So what about implicit constructors?
class.ctor.
"-5- A default constructor for a class X is a constructor of class X
that can be called without an argument. If there is no user-declared
constructor for class X, a default constructor is implicitly declared.
An implicitly-declared default constructor is an inline public member
of its class. A constructor is trivial if it is an implicitly-declared
default constructor and if: ...."
"-7- An implicitly-declared default constructor for a class is
implicitly defined when it is used to create an object of its class
type (intro.object). The implicitly-defined default constructor
performs the set of initializations of the class that would be
performed by a user-written default constructor for that class with an
empty mem-initializer-list (class.base.init) and an empty function
body"
So the implicitly-declared default constructor for Foo would be the
same as the Foo constructor declared above... x would be
uninitialised, and bar would be default initialised.
Interestingly there is no mention of the constructor being trivial or
not.
Now what about copy constructors? First consider the implicitly
defined copy constructor...
class.copy
-8- The implicitly-defined copy constructor for class X performs a
memberwise copy of its subobjects. The order of copying is the same as
the order of initialization of bases and members in a user-defined
constructor (see class.base.init). Each subobject is copied in the
manner appropriate to its type:
* if the subobject is of class type, the copy constructor for the
class is used;
* if the subobject is an array, each element is copied, in the
manner appropriate to the element type;
* if the subobject is of scalar type, the built-in assignment
operator is used.
Virtual base class subobjects shall be copied only once by the
implicitly-defined copy constructor (see class.base.init).
What about copy constructors that do no list all members in the member
initialization list?
I believe this would fall under class.base.init/4, where an integer
member would be left unitialised.
However, this doesn't agree with what you stated...?
Taras