By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,887 Members | 954 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,887 IT Pros & Developers. It's quick & easy.

dynamic allocation and values of data members

P: n/a
Consider the following classes without ctors.

class Sample
{
private:
double d_val;
double* d_ptr;
};

class Test
{
private:
int i_val;
int* i_ptr;
Sample obj;
};

Suppose I allocate
Test* t = new Test();

Since I have mentioned 'new Test()' instead of just 'new Test',
will this statement set
t->i_val to zero, t->i_ptr to null pointer, t->obj.d_val to 0.0,
t->obj.d_ptr to null pointer ?

What does the standard say in this regard ?

Kindly explain.

Thanks
V.Subramanian
Jun 27 '08 #1
Share this Question
Share on Google+
5 Replies


P: n/a
"su**************@yahoo.com, India" <su**************@yahoo.comwrites:
Consider the following classes without ctors.

class Sample
{
private:
double d_val;
double* d_ptr;
};

class Test
{
private:
int i_val;
int* i_ptr;
Sample obj;
};

Suppose I allocate
Test* t = new Test();

Since I have mentioned 'new Test()' instead of just 'new Test',
will this statement set
t->i_val to zero, t->i_ptr to null pointer, t->obj.d_val to 0.0,
t->obj.d_ptr to null pointer ?

What does the standard say in this regard ?
I just asked this question to my local C++ guru this morning, and he
said that no, these members are not implicitely initialized. You have
to do it yourself. The problem is that "[p]rimitive type member
variable like int, float etc does not have any constructors, so they
are just initialized with an undefined initial value which is often a
garbage."

Note that you should probably always define a constructor (perhaps
private), to let other objects use your class for its member and have
it automatically initialized with default values.

--
__Pascal Bourguignon__
Jun 27 '08 #2

P: n/a
Pascal J. Bourguignon wrote:
"su**************@yahoo.com, India" <su**************@yahoo.com>
writes:
>Consider the following classes without ctors.

class Sample
{
private:
double d_val;
double* d_ptr;
};

class Test
{
private:
int i_val;
int* i_ptr;
Sample obj;
};

Suppose I allocate
Test* t = new Test();

Since I have mentioned 'new Test()' instead of just 'new Test',
will this statement set
t->i_val to zero, t->i_ptr to null pointer, t->obj.d_val to 0.0,
t->obj.d_ptr to null pointer ?

What does the standard say in this regard ?

I just asked this question to my local C++ guru this morning, and he
said that no, these members are not implicitely initialized. You have
to do it yourself. The problem is that "[p]rimitive type member
variable like int, float etc does not have any constructors, so they
are just initialized with an undefined initial value which is often a
garbage."
Your guru needs to refresh his knowledge of the initialisation process.
Tell him to look things up in the Standard.
>
Note that you should probably always define a constructor (perhaps
private), to let other objects use your class for its member and have
it automatically initialized with default values.
The expression

Test* t = new Test();

in OP's case _value-initialises_ the object. That means, since 'Test'
is *not* a POD, it would call the default constructor for the class if
one existed, but since there is no user-defined constructor, every
member is _value-initialised_. For a POD type it measn _zero_-
initialised. Same proceeds to 'Sample'.

IOW, all arithmetic values are 0 and all pointers are null.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #3

P: n/a
su**************@yahoo.com, India wrote:
Consider the following classes without ctors.

class Sample
{
private:
double d_val;
double* d_ptr;
};

class Test
{
private:
int i_val;
int* i_ptr;
Sample obj;
};

Suppose I allocate
Test* t = new Test();

Since I have mentioned 'new Test()' instead of just 'new Test',
will this statement set
t->i_val to zero, t->i_ptr to null pointer, t->obj.d_val to 0.0,
t->obj.d_ptr to null pointer ?

What does the standard say in this regard ?
The original C++ standard (C++98) says that the data members of your
object will remain uninitialized. Your object has a non-POD class type,
and in the original C++ standard the '()' initializer for such types
causes a constructor call. Since the constructors in your code do
absolutely nothing, the data will remain uninitialized. I.e. there's no
difference between doing 'new Test' or 'new Test()'.

Note, that it you declare all data members as 'public', the types will
become POD and '()' initializer will cause zero-initialization for all
data members, just like you describe.

The current C++ standard (post-TC1) is different in this regard though.
The '()' initializer causes the so called "value-initialization" being
applied to your object. And since your object has no user-declared
default constructor, in this case value-initialization will lead to
zero-initialization of all data-members.

--
Best regards,
Andrey Tarasevich
Jun 27 '08 #4

P: n/a
Pascal J. Bourguignon wrote:
"[p]rimitive type member
variable like int, float etc does not have any constructors
That's not true. C++ defines constructors for them because else it
would be very difficult to create many template functions/classes which
handle variables with default values.

This is completely valid:

int i = int();

The rhs basically creates a nameless int and calls its default
constructor (which initializes it to 0). This value is then assigned to
'i'. (Naturally the compiler will optimize all this.)

This is also completely valid:

void foo(int var);

foo(int());

(It creates a nameless temporary of type int, constructs it with its
default constructor, and gives it as parameter to foo.)

Why would anyone want to do that? Why not just do "int i = 0;" and
"foo(0);"? Well, the reasoning behind this becomes clearer with templates:

template<typename T>
void foo()
{
T var = T();
...
}

This will work even if T is of type int (or any other primitive type).
Jun 27 '08 #5

P: n/a
Juha Nieminen wrote:
Pascal J. Bourguignon wrote:
>"[p]rimitive type member
variable like int, float etc does not have any constructors

That's not true.
No, that's true.
C++ defines constructors for them because else it
would be very difficult to create many template functions/classes which
handle variables with default values.
No, non-class types in C++ have no constructors. That's how it is
defined by the official language specification.

Alternative sources might decide to follow a different terminological
approach, deviating from the official terminology for one reason or
another. For example, Stroustrup's TC++PL book is known to state that
scalar types have constructors (apparently, for the sake of simplicity).
This is completely valid:

int i = int();

The rhs basically creates a nameless int and calls its default
constructor (which initializes it to 0).
No (once again, in the official terminology).

The 'int()' expression is a functional-style cast to type 'int' with an
empty set of arguments. Such a case in C++ language produces a
default-initialized unnamed temporary object of type 'int'.
Default-initialization for type 'int' means zero-initialization. That's
it. Note, that nowhere in this description any constructors are mentioned.

Your description, however, is easy to prove wrong. If type 'int' had a
default constructor, the 'int i;' declaration for an automatic variable
would call that constructor and zero-initialize the variable. This
doesn't happen. The same can be said about objects created with 'new
int'. Of course, you can explain this as some kind of exception from the
general rule, but, once again, this will be a non-standard view of the
program behavior.
This is also completely valid:

void foo(int var);

foo(int());
This is the same thing as the previous example.
(It creates a nameless temporary of type int, constructs it with its
default constructor, and gives it as parameter to foo.)
It does create a nameless temporary, but no "default constructors" are
involved here. Once again, in C++ only class types can have constructors.
Why would anyone want to do that? Why not just do "int i = 0;" and
"foo(0);"? Well, the reasoning behind this becomes clearer with templates:

template<typename T>
void foo()
{
T var = T();
...
}

This will work even if T is of type int (or any other primitive type).
True. But the generic concept that is used here is called
_initialization_, not _construction_. What we observe here is that
different (almost all) types can be _initialized_ with '()'. The
semantics of that initializer is different for different types. And only
for class types it might result in a constructor call (not for all class
types, BTW).

--
Best regards,
Andrey Tarasevich
Jun 27 '08 #6

This discussion thread is closed

Replies have been disabled for this discussion.