Instantiation of classes

D

dover

Instantiation of classes is to create objects in areas of memory. As a side
effect of that object creation, the constructor is called. Three steps can
be identified in an instantiation of a class: memory allocation, object
creation, and call constructor.

My understanding is the call of constructor that triggers memory allocation
and object creation, though I understand when in constructor, the memory has
been allocated and object created. Can someone straight this out for me?

Is it correct to say that all member variables and functions in a object
become available when inside its constructor?

Thanks!
 
V

Victor Bazarov

dover said:
Instantiation of classes is to create objects in areas of memory. As a side
effect of that object creation, the constructor is called. Three steps can
be identified in an instantiation of a class: memory allocation, object
creation, and call constructor.

My understanding is the call of constructor that triggers memory allocation
and object creation, though I understand when in constructor, the memory has
been allocated and object created. Can someone straight this out for me?

Memory is allocated first. There is basically no separate "object
creation" besides invoking a constructor. So, I see only two steps.
When the constructor body has returned to its caller (whoever that is)
the object is considered "created" (and its lifetime started).

You may forego memory allocation as part of the creation process if you
have allocated some memory yourself (and then used placement new). But,
in fact, at some point some memory has been allocated, so, it can't be
considered creation without allocation.

You cannot call a constructor. So, you're not free to "trigger" any
object creation by "calling a constructor". You just create it by
either defining an object in the scope or by using 'new' expression,
in which case memory is allocated first, then the constructor is invoked.
Is it correct to say that all member variables and functions in a object
become available when inside its constructor?

Available? What do you mean by that? All data members have been
constructed and [usually] initialised by the time the body of the
constructor is reached, yes, but "available"?...

V
 
A

Alf P. Steinbach

* dover:
Instantiation of classes is to create objects in areas of memory. As a side
effect of that object creation, the constructor is called. Three steps can
be identified in an instantiation of a class: memory allocation, object
creation, and call constructor.

Object creation (of an object of class type) is the same as successful
execution of a constructor set, so that's _one_ step when you think of a
sequence. Memory allocation is usually a side-effect of that single
conceptual act, because the main purpose of a constructor is to couple
allocation and creation so that you cannot have one without the other. To
decouple them you have to use special "unsafe" features of the language.

My understanding is the call of constructor that triggers memory allocation
and object creation, though I understand when in constructor, the memory has
been allocated and object created. Can someone straight this out for me?

You seem have two different concepts of call mixed up. One is the call in
your code, e.g.

T anObject( anArgument );
^^^^^^^^^^^^^^^^^^^^^^

or

T* pObject = new T( anArgument );
^^^^^^^^^^^^^^^

This source code call results in memory allocation + execution of the
T constructor (as well as constructors of base classes and other members,
if any). Execution of the constructor is often (ambigiously) called a
constructor call, including in the Holy Standard, but it's at a lower
level, as _one_ of the results of the source code call, and I find it much
more clear to instead refer to it as "constructor execution". When the
constructor executes the memory has been allocated.

Paraphrasing what you wrote: "My understanding is the [execution] of
constructor that triggers memory allocation and object creation, though I
understand when in constructor, the memory has been allocated and object
created." Execution of a constructor does not trigger memory allocation,
but a source code (explicit) constructor call does: except when using the
aforementioned unsafe features it results in allocation + constructor
execution, since that's the main purpose. In good code where all object
initialization happens within constructors the object can be considered to
be fully created when the constructor execution has finished successfully.

Is it correct to say that all member variables and functions in a object
become available when inside its constructor?

Execution of a constructor is a two-step process. First, initializer-list
(which involves evaluating initializer list arguments and executing other
constructors) and then body. During evaluation of initializer list
arguments you can technically access any member (§12.6.2/7), but it can be
very unsafe: all members have not been initialized yet. In the
constructor body you're a bit safer, but it's still your job, not the
compiler's, to keep track of how far initialization has progressed and at
any given point only use things that have been initialized.
 
G

Gary Labowitz

dover said:
Instantiation of classes is to create objects in areas of memory. As a side
effect of that object creation, the constructor is called. Three steps can
be identified in an instantiation of a class: memory allocation, object
creation, and call constructor.

My understanding is the call of constructor that triggers memory allocation
and object creation, though I understand when in constructor, the memory has
been allocated and object created. Can someone straight this out for me?

Is it correct to say that all member variables and functions in a object
become available when inside its constructor?

What I have been teaching for some years now seems to make sense to the
students. It goes like this:
When you instantiate an object, a routine of the system is run which I call
a "builder." This can be invoked directly with the new keyword, or
indirectly by allocation of an class type. The builder does four basic
steps:
1. Allocates the data areas declared by the class.
2. Intializes the data areas as appropriate. First any members with
constant or expression initialers are set to those values. Then, the
contructor with the signature of the object being built is called. The
constructor first executes initialization specified by the initializer list,
including selection of constructors of parent classes, if any, and after
completion runs the constructor body code.
3. Functions are made available by completing any vtable-type mechanism
for virtual functions.
4. The address of the object is then returned as the value of the
builder routine.

A lot of these steps are conceptual, and can be implemented in a variety of
ways. However, my one biggest concern is the point at which virtual
functions become available. I am guessing (unfortunately) that they are not
available to code in the constructor, and have therefore placed the table
fixup as step 3. If this is in error, then steps 2. and 3. might have to be
interchanged. Any comments on this are welcome.
 
A

Alf P. Steinbach

* Gary Labowitz:
However, my one biggest concern is the point at which virtual
functions become available. I am guessing (unfortunately) that they are not
available to code in the constructor, and have therefore placed the table
fixup as step 3. If this is in error, then steps 2. and 3. might have to be
interchanged. Any comments on this are welcome.

Virtual functions are available when the constructor execution starts, so
yes it is in error.

If this is a constructor for type T, then the dynamic type of the
object (i.e. the associated vtable in most implementations) is T,
so virtual calls will act as if the object is of type T even if the
object was instantiated from a type TDerived derived from T --
i.e. a call to virtual f() will execute the f() definition in T, not
in TDerived, even if TDerived provides an override of f().

This is FAQ item 23.3, I think (check it out).
 
G

Gary Labowitz

Alf P. Steinbach said:
* Gary Labowitz:

Virtual functions are available when the constructor execution starts, so
yes it is in error.

If this is a constructor for type T, then the dynamic type of the
object (i.e. the associated vtable in most implementations) is T,
so virtual calls will act as if the object is of type T even if the
object was instantiated from a type TDerived derived from T --
i.e. a call to virtual f() will execute the f() definition in T, not
in TDerived, even if TDerived provides an override of f().

I think you are right, so 2. and 3. should be switched. It doesn't make much
difference to my students, since they don't get into virtual in my
introductory course but will see it in the following semester.
Other than that, what do you think of this approach?
Thanks.
 
A

Alf P. Steinbach

* Gary Labowitz:
I think you are right, so 2. and 3. should be switched. It doesn't make much
difference to my students, since they don't get into virtual in my
introductory course but will see it in the following semester.
Other than that, what do you think of this approach?

I think it's an excellent idea. But I think perhaps the name "builder"
should be changed, since in the context of object construction students
who're taking some patterns course may easily confuse it with the Builder
pattern, which is also of special interest in C++ (and we already have a
religious issue due to ambiguity of "call" in this context). Just my 2c.
 
G

Gary Labowitz

I think it's an excellent idea. But I think perhaps the name "builder"
should be changed, since in the context of object construction students
who're taking some patterns course may easily confuse it with the Builder
pattern, which is also of special interest in C++ (and we already have a
religious issue due to ambiguity of "call" in this context). Just my 2c.

[Funny, I only offered 1c for your thoughts!]

I was thinking of the way houses get built, with sub-contractors. The
builder calls on "constructors" to initialize areas of the house, like paint
the bedroom blue or add a proch. I guess I could call the operation the
contractor code which calls constructors. But I can't find a good word to
call the process of doing the object construction; maybe "instantiator."
 
A

Alf P. Steinbach

* Gary Labowitz:
I think it's an excellent idea. But I think perhaps the name "builder"
should be changed, since in the context of object construction students
who're taking some patterns course may easily confuse it with the Builder
pattern, which is also of special interest in C++ (and we already have a
religious issue due to ambiguity of "call" in this context). Just my 2c.

[Funny, I only offered 1c for your thoughts!]

Well, then you got more than you bargained for. You owe me 1c... :)

I was thinking of the way houses get built, with sub-contractors. The
builder calls on "constructors" to initialize areas of the house, like paint
the bedroom blue or add a proch. I guess I could call the operation the
contractor code which calls constructors. But I can't find a good word to
call the process of doing the object construction; maybe "instantiator."

Runtime support.
Compiler generated code.
 
D

David Rubin

[snip]
What I have been teaching for some years now seems to make sense to the
students. It goes like this:
When you instantiate an object, a routine of the system is run which I call
a "builder." This can be invoked directly with the new keyword, or
indirectly by allocation of an class type. The builder does four basic
steps:
1. Allocates the data areas declared by the class.
2. Intializes the data areas as appropriate. First any members with
constant or expression initialers are set to those values.

AFAIK, these can only be integer constants such as

const int d_maxLength = 10; // maximum length of user input

and you should (or at least *can*) use an enumeration for this kind of
thing.
Then, the
contructor with the signature of the object being built is called. The
constructor first executes initialization specified by the initializer list,

In the order in which data members are declared, not listed!
including selection of constructors of parent classes, if any,

This comes after data member initialization.
and after completion runs the constructor body code.
3. Functions are made available by completing any vtable-type mechanism
for virtual functions.

Perhaps, but this insinuates that you can call these function from
within the constructor if you know that this step has been completed.
I don't think this is the right message to send. I am under the
impression that an object is not valid until *after* the constructor
returns. Only then can you call its member functions (virtual or
otherwise).
4. The address of the object is then returned as the value of the
builder routine.

The address of object is returned by 'new'. If you instantiate an
automatic object (e.g., on the stack), there are no addresses to speak
of.
A lot of these steps are conceptual, and can be implemented in a variety of
ways. However, my one biggest concern is the point at which virtual
functions become available. I am guessing (unfortunately) that they are not
available to code in the constructor, and have therefore placed the table
fixup as step 3. If this is in error, then steps 2. and 3. might have to be
interchanged. Any comments on this are welcome.

Right, construction of the "v-table" is an implementation detail of
the compiler. Therefore, these (and other) member functions are not
available to be called within the constructor. In any case, this makes
sense from a conceptual perspective since the constructor is the
object "initializer"; how can you invoke operations on a partially
initialized object?

/david
 
G

Gary Labowitz

Alf P. Steinbach said:
* David Rubin:

Wrong.

Funny. I agree with you, but I'm not sure. In parsing the initialization
list I always assumed the parser performs on the variables in the order in
which they were declared. If an object member is declared before a scalar
member, won't the constructor be called before that scalar is initialized?
[I gotta check this further.]
I have used data members as parameters to constructors, but now I'm
wondering if the standard calls for my interpretation or if I've just been
lucky.
Example:

class X
{ int a;
Y myY;
X( ) : a(7), myY(a+10) { }
};
Is this okay?
When I switch int a and Y myY around, then the Y constructor gets called
with garbage.
 
J

jeffc

dover said:
Instantiation of classes is to create objects in areas of memory. As a side
effect of that object creation, the constructor is called. Three steps can
be identified in an instantiation of a class: memory allocation, object
creation, and call constructor.

I don't know what you mean, then, by "object crdeation". To me, memory
allocation and calling the constructor creates the object. But maybe I'm
forgetting something.
My understanding is the call of constructor that triggers memory allocation
and object creation, though I understand when in constructor, the memory has
been allocated and object created. Can someone straight this out for me?

It is not my understanding that the constructor call triggers memory
allocation.
Is it correct to say that all member variables and functions in a object
become available when inside its constructor?

I don't think so. For example, polymorphism won't work until after the
constructor is finished (i.e. after the object has been fully constructed.)
 
A

Alf P. Steinbach

* jeffc:
I don't think so. For example, polymorphism won't work until after the
constructor is finished (i.e. after the object has been fully constructed.)

That is incorrect.

And this is a FAQ.

Google to find the FAQ, check out the constructor-related FAQ items (you
might also just consult your textbook, if it's not "For Dummies").
 
J

jeffc

Alf P. Steinbach said:
* jeffc: constructed.)

That is incorrect.

No it isn't.
And this is a FAQ.

Yeah, check it out sometime.
http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.3
Google to find the FAQ, check out the constructor-related FAQ items (you
might also just consult your textbook, if it's not "For Dummies").

Tell you what - why don't you Google to find whatever FAQ it is you need to
support your claim that whatever you THINK I said is wrong. Start with
"FAQs for Dummies".
 
R

Richard Herring

Alf P. Steinbach said:
* jeffc:

That is incorrect.

You're talking past each other.

What do you each mean by "polymorphism won't work", and which
constructor are you addressing?
 
J

jeffc

Richard Herring said:
What do you each mean by "polymorphism won't work", and which
constructor are you addressing?

Obviously, I mean exactly what's written in the FAQ, of which Alf is well
aware.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top