473,414 Members | 1,980 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,414 software developers and data experts.

Initialization notation

Hello,

I'm a little confused about object initialization. According to Stroustrup
(The C++ Programming Language, Special Edition, Section 10.2.3) constructor
arguments should be supplied in one of the following notations:

MyClass instance1 = MyClass(1, 2, 3);
MyClass instance2(4, 5, 6);

What's curious: the second notation variant is called an "abbreviated form"
of the first notation variant. I dind't find any further references to this
issue.

But... the first notation variant only compiles (Microsoft 7.0 compiler) if
Date has a valid copy constructor - even though it isn't used in the
expression. The assignment operator doesn't seem to be necessary...

The second notation compiles without copy constructor and assignment
operator (both declared private and not defined).

If the second notation really is an abbreviation of the first variant, both
statements should behave the same way...

So what's happening here?

Regards
Thomas

Jul 22 '05 #1
17 2042

"Thomas Lorenz" <Lo******@gmx.de> wrote in message
news:Xn***************************@198.120.69.11.. .
Hello,

I'm a little confused about object initialization. According to Stroustrup
(The C++ Programming Language, Special Edition, Section 10.2.3) constructor arguments should be supplied in one of the following notations:

MyClass instance1 = MyClass(1, 2, 3);
MyClass instance2(4, 5, 6);
But... the first notation variant only compiles (Microsoft 7.0 compiler) if Date has a valid copy constructor - even though it isn't used in the
expression. The assignment operator doesn't seem to be necessary...
Standard makes this requirement that even if the copy c'tor is elided by
implementation it should still be accessible. Theoretically MyClass(1, 2, 3)
makes a temporary object which is then copied into instance1, hence copy
c'tor is required. An implemenrtation is free to elide the copy construction
here. Still if the copy c'tor is made private it won't compile. There is no
assignment so assignment operator doesn't come into picture.

The second notation compiles without copy constructor and assignment
operator (both declared private and not defined).


Right, becuase no temporaries are being created and there is no copy
construction too.
-Sharad
Jul 22 '05 #2
"Sharad Kala" <no******************@yahoo.com> wrote in
news:2n************@uni-berlin.de:

"Thomas Lorenz" <Lo******@gmx.de> wrote in message
news:Xn***************************@198.120.69.11.. .
Hello,

I'm a little confused about object initialization. According to
Stroustrup (The C++ Programming Language, Special Edition, Section
10.2.3)

constructor
arguments should be supplied in one of the following notations:

MyClass instance1 = MyClass(1, 2, 3);
MyClass instance2(4, 5, 6);

But... the first notation variant only compiles (Microsoft 7.0
compiler)

if
Date has a valid copy constructor - even though it isn't used in the
expression. The assignment operator doesn't seem to be necessary...


Standard makes this requirement that even if the copy c'tor is elided
by implementation it should still be accessible. Theoretically
MyClass(1, 2, 3) makes a temporary object which is then copied into
instance1, hence copy c'tor is required. An implemenrtation is free to
elide the copy construction here. Still if the copy c'tor is made
private it won't compile. There is no assignment so assignment
operator doesn't come into picture.


Hmmm... this means Stroustrup is wrong. The second notation isn't really an
abbreviation of th first notation, since it doesn't impose any restrictions
on the class (except the existance of the used constructor ;)

I really don't see why the standard demands the copy constructor... The
first notation looks like...

1.) Create an instance of MyClass using the default constructor
2.) Create a temporary instance using the parametrized constructor
3.) Assign the result of 2.) to 1.)

As I said - that's how it _looks_ like. If I'd write something nonsensical
like

MyClass instance1(MyClass(1,2,3));

I'd see how the copy constructor would come into play...

So - am I missing something about copy constructors and assignment
operators?

Jul 22 '05 #3

"Thomas Lorenz" <Lo******@gmx.de> wrote in message
news:Xn***************************@198.120.69.11.. .
"Sharad Kala" <no******************@yahoo.com> wrote in
news:2n************@uni-berlin.de: Hmmm... this means Stroustrup is wrong. The second notation isn't really an

I am damn sure that won't be the case. Perhaps you are misinterpreting the
context.
abbreviation of th first notation, since it doesn't impose any restrictions on the class (except the existance of the used constructor ;)

I really don't see why the standard demands the copy constructor... The
first notation looks like...

1.) Create an instance of MyClass using the default constructor
Incorrect. We are first making the temporary using the constructor taking
three ints as parameter. In fact compiler generates no default c'tor for you
in this case.
2.) Create a temporary instance using the parametrized constructor
That's step 1.
3.) Assign the result of 2.) to 1.)
Nope, there is no assignment. Theoretically the temporary created is then
copied into instance1 using the copy c'tor.
As I said - that's how it _looks_ like. If I'd write something nonsensical
like

MyClass instance1(MyClass(1,2,3));

I'd see how the copy constructor would come into play...

So - am I missing something about copy constructors and assignment
operators?


Perhaps that,
someclass c1 = c2; // No assignment, invokes copy c'tor
c2 = c3; // Assignment

-Sharad
Jul 22 '05 #4
Hi!
MyClass instance1 = MyClass(1, 2, 3);
MyClass instance2(4, 5, 6); _first_ case, you construct two objects:
instance1 a MyClass object instantiated with the default constructor.
MyClass(1,2,3) a temporary MyClass object instantiated with the constructor
MyClass(int,int,int) (i guess ints).
_second_ case, you construct only one object:
instance2 a MyClass object instantiated with the
MyClass(int,int,int)-constructor!
get it?
What's curious: the second notation variant is called an "abbreviated
form" of the first notation variant. I dind't find any further references
to this issue. Abbreviated in the sense that you use the non-default constructor
MyClass(int,int,int) instantly to instantiate an object named instance2! So
you abbreviate in the sense that no temporary object has to be created.
But... the first notation variant only compiles (Microsoft 7.0 compiler)
if Date has a valid copy constructor - even though it isn't used in the
expression. The assignment operator doesn't seem to be necessary... of course it is used. if you have not defined an assignment operator the
copy-constructor is used instead of the assignment operator -> if this does
not work either, you get a compile error!
The second notation compiles without copy constructor and assignment
operator (both declared private and not defined). this is, because the instance2 object is instantiated with the
MyClass(int,int,int) constructor.
see, run-time example:
1) MyClass instance1 = MyClass(1, 2, 3);
instance1 -> calls MyClass()
temp.obj. MyClass(1,2,3) -> calls MyClass(int,int,int)
assign instance1 temp.obj. MyClass(1,2,3) -> call _assignment_ _op._ or
if not defined, _copy_ _constructor_!!

2) MyClass instance2(1,2,3);
instance2 -> calls MyClass(int,int,int)
If the second notation really is an abbreviation of the first variant,
both statements should behave the same way...

no, see run-time example. hope you get it now. i know the beginning is hard,
but as soon as a assignment is in place, there must always be two objects!

hope, the explanation helps you!

regards,
godfired

Jul 22 '05 #5
Thomas Lorenz wrote:
Hello,

I'm a little confused about object initialization. According to Stroustrup
(The C++ Programming Language, Special Edition, Section 10.2.3) constructor
arguments should be supplied in one of the following notations:

MyClass instance1 = MyClass(1, 2, 3);
MyClass instance2(4, 5, 6);

What's curious: the second notation variant is called an "abbreviated form"
of the first notation variant. I dind't find any further references to this
issue.

This means that they are equivalent. An implementation may use the copy
constructor instead of the assignment operator as an optimisation since
their meaning of both is equivalent.

But... the first notation variant only compiles (Microsoft 7.0 compiler) if
Date has a valid copy constructor - even though it isn't used in the
expression. The assignment operator doesn't seem to be necessary...

Yes see above. Also (just to know it) if you do not define an assignment
operator a member-copy one is implicitly provided.

The second notation compiles without copy constructor and assignment
operator (both declared private and not defined).


Yes but with another constructor.


Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #6
Ioannis Vranos posted:
Thomas Lorenz wrote:
Hello,

I'm a little confused about object initialization. According to
Stroustrup (The C++ Programming Language, Special Edition, Section
10.2.3) constructor arguments should be supplied in one of the
following notations:

MyClass instance1 = MyClass(1, 2, 3);
MyClass instance2(4, 5, 6);

What's curious: the second notation variant is called an "abbreviated
form" of the first notation variant. I dind't find any further
references to this issue.

This means that they are equivalent. An implementation may use the copy
constructor instead of the assignment operator as an optimisation since
their meaning of both is equivalent.


If the assignment operator is used in the above AT ALL, then you're not
dealing with a C++ compiler.

Taking the line:

MyClass instance1 = MyClass(1,2,3);

The C++ compiler has two options:

A) Construct a temporary with the constructor arguments 1,2,3. Copy-
construct "instance1" from this temporary. Destroy the temporary.

B) Construct instance1 with the constructor arguments 1,2,3.
If the assignment operator gets involved, burn that compiler.
-JKop
Jul 22 '05 #7
Gottfried Eibner <_gottfried._eibner@_univie._ac._at> wrote in
news:41***********************@usenet.univie.ac.at :
What's curious: the second notation variant is called an "abbreviated
form" of the first notation variant. I dind't find any further
references to this issue.

Abbreviated in the sense that you use the non-default constructor
MyClass(int,int,int) instantly to instantiate an object named
instance2! So you abbreviate in the sense that no temporary object has
to be created.

Ah! Interesting interpretation. Didn't occur to me :) I interpreted
"abbreviation" as "shorthand", implying equivalent in every respect. Like
some other "shorthand" notation the language allows...
But... the first notation variant only compiles (Microsoft 7.0
compiler) if Date has a valid copy constructor - even though it isn't
used in the expression. The assignment operator doesn't seem to be
necessary...

of course it is used. if you have not defined an assignment operator
the copy-constructor is used instead of the assignment operator -> if
this does not work either, you get a compile error!

Nope. The compiler wants the copy constructor. It doesn't matter
if the assignment operator is defined or not - it is never used.

Here's my example code:

#include <iostream>
using namespace std;

class E {
public:
E() : m_s() {cout << "E()" << endl;};
E(const string& s) : m_s(s) {cout << "E('" << s << "')" << endl;};
E(const E& right) : m_s(right.m_s) {cout << "E(const E&)" << endl;};
E& operator=(const E& right) {cout << "E::operator=(const E&)" << endl;
return *this;}
private:
string m_s;
};

int main(int argc, char* argv[])
{

cout << "Notation 1" << endl;
E e1 = E("3");
cout << "Notation 2" << endl;
E e2("4");
cout << "finish" << endl;
}

Output is
Notation 1
E('3')
Notation 2
E('4')
finish

If I move the assignment operator to the 'private' section, the code
compiles and runs just fine. If I move the copy constructor to the
'private' section, the code doesn't compile...

As far as I know,

E e1 = E("3");

is meant to create a temporary instance of E (containing '3'), and copy
said temporary into e1 (using the copy constructor). The compiler probably
eliminates the unnecessary copy-construction of the temporary, but still
requests the presence of the copy constructor.

My confusion really was about the meaning of "abbreviation" in the book.

Thanks for your answer, nonetheless ;)

Thomas
Jul 22 '05 #8

This means that they are equivalent. An implementation may use the copy
constructor instead of the assignment operator as an optimisation since
their meaning of both is equivalent.


Really ? I don't think so. Could you quote the standard to this effect.
Jul 22 '05 #9
Ioannis Vranos <iv*@guesswh.at.grad.com> wrote in
news:ce*********@ulysses.noc.ntua.gr:
Thomas Lorenz wrote:
Hello,

I'm a little confused about object initialization. According to
Stroustrup (The C++ Programming Language, Special Edition, Section
10.2.3) constructor arguments should be supplied in one of the
following notations:

MyClass instance1 = MyClass(1, 2, 3);
MyClass instance2(4, 5, 6);

What's curious: the second notation variant is called an "abbreviated
form" of the first notation variant. I dind't find any further
references to this issue.

This means that they are equivalent. An implementation may use the
copy constructor instead of the assignment operator as an optimisation
since their meaning of both is equivalent.

But they _can't_ really be equivalent. Unless the standard proscribes calls
to copy constructor or assignment operator in the first variant. Only then
would it be possible to use either notation for each variant and achieve
the same results.

At least for my compiler these calls are not equivalent, because notation 1
requires the presence of a copy constructor.
But... the first notation variant only compiles (Microsoft 7.0
compiler) if Date has a valid copy constructor - even though it
isn't used in the expression. The assignment operator doesn't seem to
be necessary...

Yes see above. Also (just to know it) if you do not define an
assignment operator a member-copy one is implicitly provided.

I'm quite aware of that fact :)

The second notation compiles without copy constructor and assignment
operator (both declared private and not defined).


Yes but with another constructor.

No, it uses MyClass(int, int, int) too...

Regards
Thomas
Jul 22 '05 #10
JKop <NU**@NULL.NULL> wrote in news:9h******************@news.indigo.ie:
[...]
If the assignment operator is used in the above AT ALL, then you're not
dealing with a C++ compiler. It doesn't use it. So I'm safe for now...
Taking the line:

MyClass instance1 = MyClass(1,2,3);

The C++ compiler has two options:

A) Construct a temporary with the constructor arguments 1,2,3. Copy-
construct "instance1" from this temporary. Destroy the temporary.

B) Construct instance1 with the constructor arguments 1,2,3.
If the assignment operator gets involved, burn that compiler.


I dug up some old version of the C++ ISO standard on the net (Draft from
December '96): ftp://ftp.maths.warwick.ac.uk/pub/c++/std/cd2/

OK, it's outdated, but I don't want to wait for the book :)

Anyway if you search for the keyword copy-initialization (that's apparently
the term for an expression like 'T x = a'), paragraph 8.5.14 requires the
compiler to enumerate the applicable constructors and choose the best one
through overload resolution (source and destination type are identical).
Than that constructor is called to initialize the object.

So the compiler should do 'MyClass instance1(1,2,3);'.

Well apparently the MS compiler treats copy-initialization with the same
type like a copy-initialization with any other type, which is to create a
temporary, and use the best match constructor to initialize the variable.
Since source and destination type are the same, that would be the copy
constructor. So that's why the compiler wants to see it. Since the standard
allows the elimination of the temporary by direct initialization, it is
never called.

So the compiler does 'MyClass instance1(MyClass(1,2,3));' and drops
temporary and copy constructor call.

So apparently Stroustrup is right, and the compiler is wrong...

Did I get this right?

Thomas
Jul 22 '05 #11
"Sharad Kala" <no******************@yahoo.com> wrote in
news:2n************@uni-berlin.de:
Hmmm... this means Stroustrup is wrong. The second notation isn't
really

an

I am damn sure that won't be the case. Perhaps you are misinterpreting
the context.


I'm quite sure you're right.
I'm now (almost) sure the compiler got things wrong (see other post in this
thread).

Probably I'll order a copy of the standard. Didn't think it would be useful
in day to day work until now...

Thanks
Thomas
Jul 22 '05 #12
Gottfried Eibner wrote:

But... the first notation variant only compiles (Microsoft 7.0 compiler)
if Date has a valid copy constructor - even though it isn't used in the
expression. The assignment operator doesn't seem to be necessary...

of course it is used. if you have not defined an assignment operator the
copy-constructor is used instead of the assignment operator -> if this does
not work either, you get a compile error!


????
Do you make your own rules or what?
In this question we are dealing with intialization. operator= is *never*
used for initialization. It is always a constructor involved, in this
case the copy constructor.

Initialization and assignment are 2 different things and one needs
to differentiate between them otherwise such nonsense as above emerges.
--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #13
Thomas Lorenz wrote:

JKop <NU**@NULL.NULL> wrote in news:9h******************@news.indigo.ie:
[...]
If the assignment operator is used in the above AT ALL, then you're not
dealing with a C++ compiler. It doesn't use it. So I'm safe for now...
Taking the line:

MyClass instance1 = MyClass(1,2,3);

The C++ compiler has two options:

A) Construct a temporary with the constructor arguments 1,2,3. Copy-
construct "instance1" from this temporary. Destroy the temporary.

B) Construct instance1 with the constructor arguments 1,2,3.
If the assignment operator gets involved, burn that compiler.


I dug up some old version of the C++ ISO standard on the net (Draft from
December '96): ftp://ftp.maths.warwick.ac.uk/pub/c++/std/cd2/

OK, it's outdated, but I don't want to wait for the book :)

Anyway if you search for the keyword copy-initialization (that's apparently
the term for an expression like 'T x = a'), paragraph 8.5.14 requires the
compiler to enumerate the applicable constructors and choose the best one
through overload resolution (source and destination type are identical).
Than that constructor is called to initialize the object.

So the compiler should do 'MyClass instance1(1,2,3);'.


No. That constructor can't be used.

In

MyClass instance = MyClass( 1, 2, 3 );

then on the right hand side of the '=' (but beware: this is not an asignment!)
there is a MyClass object. On the left hand side of the '=' there is a MyClass
object. This means: initialize a MyClass object by using another MyClass object.
And the best constructor for such an initialization is the copy constructor.
Thus the compiler treats the above as

MyClass instance( MyClass( 1, 2, 3) );

It really has no other choice. The 'inner' MyClass object is constructed
as usual, using a ctor which takes 3 int.

That much for the theory. But now for practice. The people writing the C++
standard realized that there would be 2 completely different versions:

MyClass instance( 1, 2, 3 );
MyClass instance = MyClass( 1, 2, 3 );

which eventuall lead up to the very same result. Which one to choose is just
a matter of personal writing preference. All would be well, if the second version
wouldn't require much more overhead due to the creation of the temporary. Thus
they explicitely allowed the compiler to optimize version 2 into version 1, even
if both are intentionally *not* equivalent.

Well apparently the MS compiler treats copy-initialization with the same
type like a copy-initialization with any other type, which is to create a
temporary, and use the best match constructor to initialize the variable.
Yep. And it is correct in doing this.
Since source and destination type are the same, that would be the copy
constructor. So that's why the compiler wants to see it. Since the standard
allows the elimination of the temporary by direct initialization, it is
never called.
Yes. And the standard explicitely states, that even if this optimization is
done, the copy constructor has to be accessible.

So the compiler does 'MyClass instance1(MyClass(1,2,3));' and drops
temporary and copy constructor call.

So apparently Stroustrup is right, and the compiler is wrong...
In which way did you reach to that conclusion? What the compiler does
can be described by using the standards document. There is nothing wrong
in what the compiler does.

Did I get this right?

Thomas

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #14
Karl Heinz Buchegger <kb******@gascad.at> wrote in
news:41***************@gascad.at:
Well apparently the MS compiler treats copy-initialization with the
same type like a copy-initialization with any other type, which is to
create a temporary, and use the best match constructor to initialize
the variable.


Yep. And it is correct in doing this.
Since source and destination type are the same, that would be the
copy constructor. So that's why the compiler wants to see it. Since
the standard allows the elimination of the temporary by direct
initialization, it is never called.


Yes. And the standard explicitely states, that even if this
optimization is done, the copy constructor has to be accessible.

So the compiler does 'MyClass instance1(MyClass(1,2,3));' and drops
temporary and copy constructor call.

So apparently Stroustrup is right, and the compiler is wrong...


In which way did you reach to that conclusion? What the compiler does
can be described by using the standards document. There is nothing
wrong in what the compiler does.


By not really thinking through my own argumentation, I guess. I mentally
branched into the wrong case. The compiler apparently _does_ the right
thing.

And according to your reasoning, Stroustrup is right, too. Possibly guilty
of simplification, but right, nonetheless.

Well, thanks for your precise answer to my confused questions. I guess,
that settles the matter.

And thanks to all participants.

Regards
Thomas
Jul 22 '05 #15
Ioannis Vranos wrote in news:ce*********@ulysses.noc.ntua.gr in
comp.lang.c++:

MyClass instance1 = MyClass(1, 2, 3);

This means that they are equivalent. An implementation may use the
copy constructor instead of the assignment operator as an optimisation
since their meaning of both is equivalent.


There is no assignement in the above, only initialization.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #16
Thomas Lorenz wrote:
I'm quite sure you're right.
I'm now (almost) sure the compiler got things wrong (see other post in this
thread).

Probably I'll order a copy of the standard. Didn't think it would be useful
in day to day work until now...


On page 191 the standard mentions such a case. So indeed on assignment
*upon definition* the copy constructor is used.


So

whatever s1;

// ...
whatever x=s1;
is equivalent to
whatever x(s1);

If the original poster wants an assignment to happen after an
initialisation of the object with its default constructor, then he
should do it in the style:
whatever x;

x=s1;
without any additional cost to what he wants to do (but of course with
additional cost to the use of copy constructor directly).


Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #17
Sharad Kala wrote:
This means that they are equivalent. An implementation may use the copy
constructor instead of the assignment operator as an optimisation since
their meaning of both is equivalent.

Really ? I don't think so. Could you quote the standard to this effect.


You are right and I was wrong. It is not up to the compiler to decide.
The standard requires the copy constructor to be used on assignment
*upon definition* (initialisation), which is also the rational thing to do.


Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

50
by: Charles Stapleton | last post by:
Given the folowing class class Ctest{ public: Ctest( int i, int j) :a(i) { b = j; } private: int a, b; } When creating an object of type Ctest, what advantage is there to setting
49
by: Luke Meyers | last post by:
Lately I find myself increasingly preferring the practice of going ever-so-slightly out of my way to avoid the use of the form of initialization which uses the '=' symbol, on the grounds that it...
7
by: Thomas Matthews | last post by:
Hi, When assigning variables at initialization, is the following allowed: class Field; int main(void) { Field * p_field(NULL); return EXIT_SUCCESS;
11
by: asdf | last post by:
The oder of member initialization is the order in which the members are defined. So the following code is problematic: class X{ int i; int j; public: X(int val):j(val),i(j){}
15
by: akomiakov | last post by:
Is there a technical reason why one can't initialize a cost static non- integral data member in a class?
2
by: quadraticformula | last post by:
Hey, quick question for anyone willing to listen. I've always wondered why I can initialize an array of structs with something like this (where "..." represents the 14 separate values for the...
5
by: joer3 | last post by:
When you initialize a variable like this: X var; var = X(); The equals sign is called the assignment operator and you can overload it and indeed should in many cases. However, when you...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.