Number of ways to create an object

P

Peter Ammon

A friend was asked "How many ways are there to create an object in C++?"
in an interview. Apparently, the "right" answer was eleven. Does
anyone know how the interviewer arrived at that number? Is this fact
well known (if true)?
 
A

Alf P. Steinbach

A friend was asked "How many ways are there to create an object in C++?"
in an interview.

The only meaningful answer is 1: by calling a constructor.

Lest idiots yet again object to that terminology: it's the one employed
by the Holy Standard.

Apparently, the "right" answer was eleven. Does
anyone know how the interviewer arrived at that number? Is this fact
well known (if true)?

Any number might be considered correct under suitable assumptions and
using suitable definitions, e.g. of "ways", "create", "object".
 
J

jeffc

Peter Ammon said:
A friend was asked "How many ways are there to create an object in C++?"
in an interview. Apparently, the "right" answer was eleven. Does
anyone know how the interviewer arrived at that number? Is this fact
well known (if true)?

That "fact" is not well known, if true. Sounds like one of those goofy
questions where the interviewer has a "one up" by already researching an
obscure problem ahead of time that you couldn't know. Maybe he just wanted
to see how you think about things and get the ball rolling, not come up with
"11". (Frankly, I'm reminded of This Is Spinal Tap at this moment.)

class A;

A a; // 1
A* pA = new A; // 2
f(A()); // 3
etc.
 
R

Ron Natalie

Alf P. Steinbach said:
The only meaningful answer is 1: by calling a constructor.

It's wrong. You can't call the constructor. A constructor is called by the
implementation as a byproduct of object created.
Lest idiots yet again object to that terminology: it's the one employed
by the Holy Standard.

No it's not. Even with your quibbling over "is called" verses "calling"
your answer is WRONG. There are two DISTINCT steps in object
creation specifically listed in the standard:

1. First storage is obtained
2. Then construction occurs.

Your incorrect answer totally omits the first step.
 
R

Ron Natalie

Peter Ammon said:
A friend was asked "How many ways are there to create an object in C++?"
in an interview. Apparently, the "right" answer was eleven. Does
anyone know how the interviewer arrived at that number? Is this fact
well known (if true)?

Well without any better explanation of the problem, any answer might be
correct. Object creation is divided into two steps:

1. Obtaining storage.
2. Construction.

The first is divided into three main categories:

1. Static storage duration, which includes static parts of classes, static variables at namespace
scope, and static variables within functions.
2. Automatic storage duration (your non-static local variables inside functions as well as temporaries).
3. Dynamic storage duration: i.e., that obtained via new. Which includes regular single
object new expressions, array new expressions, each of which can have additional
"placement arguments"

The second phase can be divided into three groups:

1. Default initialization
2. Copy initialization
3. Direct initialization..

I can easily come up with any number from 3 to over 24 different flavors of object creation
depending on what he means by "way".
 
D

David Harmon

A friend was asked "How many ways are there to create an object in C++?"
in an interview. Apparently, the "right" answer was eleven. Does
anyone know how the interviewer arrived at that number? Is this fact
well known (if true)?

I guarantee that if you post his list of eleven "ways", people here will
come up with _both_ additional "ways" that are just as valid as some on
the list, and reasons why some of the eleven are really the "same thing"
and shouldn't be counted twice.
 
E

E. Robert Tisdale

Ron said:
Alf said:
The only meaningful answer is 1: by calling a constructor.

It's wrong. You can't call the constructor.
A constructor is called by the implementation
as a byproduct of object created.
Lest idiots yet again object to that terminology:
it's the one employed by the Holy Standard.

No it's not.
Even with your quibbling over "is called" verses "calling"
your answer is WRONG. There are two DISTINCT steps
in object creation specifically listed in the standard:

1. First storage is obtained
2. Then [initialization] occurs.

Your incorrect answer totally omits the first step.

Actually, these two steps define construction.
The constructor function is actually an initializer.
The compiler emits code to

1. allocate storage for the object then
2. "calls" the "constructor" to initialize it.

You can think of a constructor for class C
as a class "friend" function:

C C(. . .);

that returns an object of type C
which can be used in an expression.
 
P

Peter van Merkerk

David Harmon said:
I guarantee that if you post his list of eleven "ways", people here will
come up with _both_ additional "ways" that are just as valid as some on
the list, and reasons why some of the eleven are really the "same thing"
and shouldn't be counted twice.

Whatever the correct answer is (if there is any at all), who cares? I think
many skilled C++ can't answer that question, and for those who can it says
nothing about their C++ programming skills. You could question however the
C++ skills of the person who asked the question.
 
D

David Harmon

I can easily come up with any number from 3 to over 24 different flavors of object creation
depending on what he means by "way".

Well, it would be pretty difficult to come up with eleven by your
method, since it is a prime number.
 
A

Alf P. Steinbach

It's wrong. You can't call the constructor.

No? See below.

A constructor is called by the implementation

The machine code that achieves that amazing feat is irrelevant.

Why do you keep on harking about the machine-code level?


as a byproduct of object created.


No it's not.

It is, as you well know from earlier discussions. Have you forgotten? In
that case, allow me to attempt to refresh your failing (ailing?) memory:


§12.1/2 ... an explicit type conversion using the functional notation (5.2.3)
will cause a constructor to be CALLED to initialize an object.

§12.1/5 A default constructor for a class X is a constructor of class X that
can be CALLED without an argument.

§12.1/8 Default constructors are CALLED implicitly to create class objects
of automatic storage duration (3.7.1, 3.7.2) defined without an
initializer (8.5), are CALLED to create class objects of dynamic
storage duration (3.7.3) created by a new-expression in which the
new-initializer is omitted (5.3.4), or are CALLED when the explicit
type conversion syntax (5.2.3) is used.

--> Note especially the distinction here between CALLED IMPLICITLY
and simply CALLED. Perhaps you've been misled to think the
former is always the case, and that's what your apparent
hang-up about the machine code level is about?

--> Note also: "constructors" ... "are CALLED".


§12.1/9 [Note: 12.6.2 described the order in which constructors for base
classes and non-static data members CALLED and describes how arguments
can be specified for the CALLS to these constructors.]

§12.1/13 ... [Note: explicit constructor CALLS do not yield lvalues, see 3.10].


And so on.

Feel free to CALL it anything you like.

But don't feed claims about constructors being non-callable to the newsgroup.



Even with your quibbling over "is called" verses "calling"
your answer is WRONG. There are two DISTINCT steps in object
creation specifically listed in the standard:

1. First storage is obtained
2. Then construction occurs.

Your incorrect answer totally omits the first step.


"Create" can be subdivided, and further prerequisites added, so what?

I applaud the insight you've had that there must be some storage.

On the other hand, logic is otherwise totally absent in your reply; in
particular, I did not omit or include any details about creation other
than the need for a constructor call (in the cases of the only reasonable
interpretation of "object" in the question at hand).
 
R

Ron Natalie

E. Robert Tisdale said:
2. Then [initialization] occurs.

Thank you for the gratuitous editing of my post. I specifically said CONSTRUCTION
because that is what the standard says.
Actually, these two steps define construction.
The constructor function is actually an initializer.
The compiler emits code to

1. allocate storage for the object then
2. "calls" the "constructor" to initialize it.

OK...I agree
You can think of a constructor for class C
as a class "friend" function:

C C(. . .);

that returns an object of type C
which can be used in an expression.

Only if I want to be confused or wrong....with the exception of certain uses
of the conversion expression that looks oddly like it might be a constructor
call (which it isn't), the constructor is transparent to object creation:

C x(34,55); // doesn't look much like a function call
new X; // doesn't look much like a function call

etc...
 
R

Ron Natalie

Alf P. Steinbach said:
No? See below.

No. You seem to refuse to understand standard English. Is called by is
not the same meaning as I am calling.
The machine code that achieves that amazing feat is irrelevant.

Why do you keep on harking about the machine-code level?
I'm not giving a hoot about the machine code leve. The standard says
you aren't calling a constructor, you're NOT. As a matter of fact, it's
not even a single constructor that is called. Constructors are called for
all the subobjects as well. Both in theory and in practice, I tell the compiler
(via one of the 3 or 11 or how many ways) that I want an object and it:
1. Gets some memory
2. Invokes all the constructor code.

I'm not calling the constructor, where would I get the memory ?








ou well know from earlier discussions. Have you forgotten? In
that case, allow me to attempt to refresh your failing (ailing?) memory:


§12.1/2 ... an explicit type conversion using the functional notation (5.2.3)
will cause a constructor to be CALLED to initialize an object.

I know well, but unlike you I can understand the language of the standard
in addition to quoting it. Note it says "cause the constructor to be called."
It doesn't say the programmer is calling it. As it has been explained to you
a number of times, the standard specfiically says constructors do not have
names, do not participate in name resolution, and hence can not be called
by the user code. All a user can do is cause an object to be created and
let the constructors be called for him.
 
R

Ron Natalie

David Harmon said:
Well, it would be pretty difficult to come up with eleven by your
method, since it is a prime number.

This always reminds me of the story where a group of high school kids are sitting
in sex ed class. The teacher asks "How many sexual positions are there?" An eager
kid in the first row starts waving his hand, I know, I know, twenty three! twenty three!
The teacher ignores him and picks a shy girl in the back, and repeats the question to
her. She hesitates and says the only position she is aware of is the one with the man
on the top and the woman on the bottom. The eager beaver in the front row continues
waving his hand yelling TWENTY FOUR, TWENTY FOUR!
 
D

Default User

Ron said:
No it's not. Even with your quibbling over "is called" verses "calling"
your answer is WRONG. There are two DISTINCT steps in object
creation specifically listed in the standard:

1. First storage is obtained
2. Then construction occurs.

Your incorrect answer totally omits the first step.


Some objects never go through phase 2 either.



Brian Rodenborn
 
A

Alf P. Steinbach

No. You seem to refuse to understand standard English. Is called by is
not the same meaning as I am calling.
I'm not giving a hoot about the machine code leve. The standard says
you aren't calling a constructor, you're NOT.

Hark up a reference where the standard says you're not calling a constructor
(other than the one about PODs, of course).

As a matter of fact, it's
not even a single constructor that is called. Constructors are called for
all the subobjects as well.

Ron, you forgot about base classes. Yikes!


Both in theory and in practice, I tell the compiler
(via one of the 3 or 11 or how many ways) that I want an object and it:
1. Gets some memory
2. Invokes all the constructor code.

I'm not calling the constructor, where would I get the memory ?

If you don't call a constructor I don't see the relevance of the question.


I know well, but unlike you I can understand the language of the standard
in addition to quoting it. Note it says "cause the constructor to be called."
It doesn't say the programmer is calling it.

In your opinion then, when you cause a constructor to be called you're not
calling it.

"But judge, I just _caused_ that man to die, I didn't kill him."

How dense are you?


As it has been explained to you a number of times

You mean, as _you_ have tried to dissemble a number of times, ...

the standard specfiically says constructors do not have names,
Right.


do not participate in name resolution
Right.


and hence can not be called by the user code.

Wrong, it does not say that. If you disagree, hark up a reference.
 
R

Ron Natalie

Default User said:
Some objects never go through phase 2 either.
That is correct. I simplified the second step, there is an "if the constructor isn't trivial"
in the standard.
 
R

Ron Natalie

Alf P. Steinbach said:
Hark up a reference where the standard says you're not calling a constructor
(other than the one about PODs, of course).

First two paragraphs of 12.1, as we pointed out to you before.
Ron, you forgot about base classes. Yikes!

Base classes are subobjects.
In your opinion then, when you cause a constructor to be called you're not
calling it.

Correct. I'm not the one doing the calling. I can't call the constructor.
All I can do is create an object and trust the compiler to invoke it.

When I run a program, I cause main to get called, but I do not (and can not
call it).

"But judge, I just _caused_ that man to die, I didn't kill him."

Not the same construction in English. But, it's more along the lines of:

I called the hit man, but I didn't pull the trigger.
Wrong, it does not say that. If you disagree, hark up a reference.

Show me how you call one. The thing you insist is a constructor call is
the syntax of an explicit type conversion. It is detailed in 5.2.3 and,
1. Is not a function call whose syntax and semantics are defined in 5.2.2.
A function call is an expression followed by a set of parens (with the
arguments). There is NO way to make up syntactically the expression
to the left side of the parens because a constructor doesn't have a name
and a type name by itself isn't an expression.
2. Does more than just call the constructor. Constructors don't return
anything, constructors don't allocate memory, the constructor doesn't
invoke the subobject initialization.
 
A

Alf P. Steinbach

First two paragraphs of 12.1,

Quote 'em.

Point out where it says you're not calling a constructor.


as we pointed out to you before.

Is that the royal "we"?

In your previous message you referred to yourself as "it".



Base classes are subobjects.

Okay, you didn't forget about base classes, you just assumed that any
intelligent reader would understand what you meant because any other
interpretation would be unreasonable.

I'll grant you that.

Now, why don't you extend the same courtesy?


Correct. I'm not the one doing the calling. I can't call the constructor.
All I can do is create an object and trust the compiler to invoke it.

When I run a program, I cause main to get called, but I do not (and can not
call it).



Not the same construction in English. But, it's more along the lines of:

I called the hit man, but I didn't pull the trigger.

So you just caused the man to be killed, but in your opinion didn't kill
him.

Similarly, when p is a pointer to an object and m a virtual method, when you
write p->m() you just _cause_ the implementation to look up the method and
then call it. At least, if you're consistent. Which you've not been so far.


Show me how you call one.

Well, that's rather basic. Here is one form, assuming C is a non-POD class:


C o; // Calls default constructor.


The thing you insist is a constructor call is the syntax of an explicit
type conversion.

I have not.

If you ("we", "it") think I have written about a "thing" and insisted
that that is a constructor call, quote me.


It is detailed in 5.2.3 and,
1. Is not a function call whose syntax and semantics are defined in 5.2.2.
A function call is an expression followed by a set of parens (with the
arguments). There is NO way to make up syntactically the expression
to the left side of the parens because a constructor doesn't have a name
and a type name by itself isn't an expression.
2. Does more than just call the constructor. Constructors don't return
anything, constructors don't allocate memory, the constructor doesn't
invoke the subobject initialization.

That's not quoting from the Holy Standard, as it might seem to be: it's
rambling. Some of it has basis in fact, some of it in imagination. I asked
for a quote.
 
R

Ron Natalie

E. Robert Tisdale said:
How about

C x = C(34, 55);
I only needed one counter example to disprove your assertion. While to the untrained
eye C(34,55) appears to be a function call it isn't. Not all things that have parens in
them are function calls. C(34,55) is an explicit type conversion, just as the following
aren't function calls either:
sizeof(34);
return(3);
 

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

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top