Instansiating an object

T

Tony Johansson

Hello!

Assume I have a class named Student and I instansiate an object called kasia
in this way.
Student kasia(100);

What the difference if I instead instansiate this kasia in this way.
Student kasia = Student(100);

I assume these two are equivalent. But I always use former way.

//Tony
 
S

shivank

in Student kasia(100); a constructor with one argument (may be int)
will be called.
in Student kasia = Student(100); the copy constructor is invoked. If
you have not defined your own, then compiler generates it by default
which will make a copy of values of all data members in the target.
One should normally prefer the former way.

-- Regards
Shivank
 
J

Jaspreet

Tony said:
Hello!

Assume I have a class named Student and I instansiate an object called kasia
in this way.
Student kasia(100);

This will work only if you have a parameterised constructor which
accepts an integer as a parameter. Soo, in this case the class decl.
should have :

Student(int);

as one of the constructors, considering you do not have any default
argument constructor.
What the difference if I instead instansiate this kasia in this way.
Student kasia = Student(100);

I assume these two are equivalent. But I always use former way.

No these two are not same. Actually this will not call the copy
constructor because you need to pass a copy of an existing object. If
it were, say:
Student kasia(100); // calls 1-argument constructor
Student Tony(kaisa); // calls the copy constructor

then instantiating Tony would have called a copy constructor.

However, In you case if the call has to go through it would require
something like:
Student(Student );

in your class decl. But if you do that, the compiler (gcc 3.2.2)would
complain saying that you probably wanted a copy constructor, so you
should have had :

Student(const Student &)

as the decl..

So, bottom line is your first call is fine and it makes a call to a
1-argument constructor to instantiate your Student object. Your second
call is not correct and it would NOT call a copy constructor.

Hope that makes some sense..
 
R

Rapscallion

Tony said:
Assume I have a class named Student and I instansiate an object called kasia
in this way.
Student kasia(100);

This is C++.
What the difference if I instead instansiate this kasia in this way.
Student kasia = Student(100);

This is Java (almost, you forgot the 'new').
I assume these two are equivalent. But I always use former way.

I wouldn't program Java in C++. ;-)

R.C.
 
R

Rolf Magnus

Tony said:
Hello!

Assume I have a class named Student and I instansiate an object called
kasia in this way.

You mean you instantiate the class, not the object. Creating an instance of
the class (i.e. an object) means to instantiate that class.
Student kasia(100);

What the difference if I instead instansiate this kasia in this way.
Student kasia = Student(100);

The first one will create kasia as an instance of Student and initialize it
with 100.
The second one first creates a nameless temporary Student instance and
initializes it with 100. Then, kasia is initialized from that temporary by
the copy constructor. Then the temporary is destroyed. Many modern
compilers will optimize the temporary away, and the C++ standard explicitly
allows that, but even then, a copy constructor must be accessible.
 
K

Krishanu Debnath

Rolf said:
The second one first creates a nameless temporary Student instance and
initializes it with 100. Then, kasia is initialized from that temporary by
the copy constructor. Then the temporary is destroyed. Many modern
compilers will optimize the temporary away, and the C++ standard explicitly
^^
I could not find out the relavent C&V from standard. :(
Anyone kind enough?

Thanks
Krishanu
 
R

Rolf Magnus

Jaspreet said:
No these two are not same. Actually this will not call the copy
constructor because you need to pass a copy of an existing object.

What do you mean by "a copy of an existing object"? You need to pass an
existing object, and Student(100) creates such an object.
However, In you case if the call has to go through it would require
something like:
Student(Student );

No, it wouldn't. Such a constructor would be nonsense anyway, since it would
create an endless loop.
in your class decl. But if you do that, the compiler (gcc 3.2.2)would
complain saying that you probably wanted a copy constructor, so you
should have had :

Student(const Student &)

as the decl..

Yes, or just let the compiler generate one.
So, bottom line is your first call is fine and it makes a call to a
1-argument constructor to instantiate your Student object. Your second
call is not correct and it would NOT call a copy constructor.

Where did you get that from?
Hope that makes some sense..

It doesn't.
 
R

Rolf Magnus

Krishanu said:
^^
I could not find out the relavent C&V from standard. :(
Anyone kind enough?

8.5 Initializers

14
[...] The function selected is called with the initializer expression as its
argument; if the function is a constructor, the call initializes a temporary
of the destination type. The result of the call (which is the temporary for
the constructor case) is then used to direct-initialize, according to the
rules above, the object that is the destination of the copy-initialization.
In certain cases, an implementation is permitted to eliminate the copying
inherent in this direct-initialization by constructing the intermediate
result directly into the object being initialized; see 12.2, 12.8.

12.8 Copying class objects

15
Whenever a temporary class object is copied using a copy constructor, and
this object and the copy have the same cv-unqualified type, an
implementation is permitted to treat the original and the copy as two
different ways of referring to the same object and not perform a copy at
all, even if the class copy constructor or destructor have side effects.
[...]
 
J

Jaspreet

Rolf said:
What do you mean by "a copy of an existing object"? You need to pass an
existing object, and Student(100) creates such an object.

Oops slip of the keyboard.
No, it wouldn't. Such a constructor would be nonsense anyway, since it would
create an endless loop.
Thats why I said the compiler will complain.
Yes, or just let the compiler generate one. Yes thats true..


Where did you get that from?
Try having a copy constructor in your program and make the second call.
It will not call the copy constructor. Try compiling the following
program.

#include <iostream>

using namespace std;

class stud
{
public:
stud (stud &s)
{
cout<<endl<<"copy";
}
stud(int a)
{
cout<<endl<<"1-arg constructore";
}
};
int main()
{
stud s=stud (5);
return (EXIT_SUCCESS);
}
It doesn't.
Try compiling the above program or even try:

#include <iostream>

using namepsace std;

class stud
{
};

int main()
{
stud s=stud(5);
return (EXIT_SUCCESS);
}

I got the following errors: (gcc 3.2.2)
obj1.cc: In function `int main()':
obj1.cc:11: no matching function for call to `stud::stud(int)'
obj1.cc:6: candidates are: stud::stud()
obj1.cc:6: stud::stud(const stud&)

Not sure how, the call "stud s=stud(5);" would call a copy constructor.
It should not. Let me know if I am wrong..

It might make some sense!!!
 
R

Rolf Magnus

Jaspreet said:
Try having a copy constructor in your program and make the second call.
It will not call the copy constructor.

Right. It will try to, but it can't because your copy constructor takes a
non-const reference, and C++ forbids binding a temporary to a non-const
reference.
Try compiling the following program.

#include <iostream>

using namespace std;

class stud
{
public:
stud (stud &s)
{
cout<<endl<<"copy";
}
stud(int a)
{
cout<<endl<<"1-arg constructore";
}
};
int main()
{
stud s=stud (5);
return (EXIT_SUCCESS);
}

Try compiling the above program or even try:

#include <iostream>

using namepsace std;

class stud
{
};

int main()
{
stud s=stud(5);
return (EXIT_SUCCESS);
}

I got the following errors: (gcc 3.2.2)
obj1.cc: In function `int main()':
obj1.cc:11: no matching function for call to `stud::stud(int)'
obj1.cc:6: candidates are: stud::stud()
obj1.cc:6: stud::stud(const stud&)

What does that have to do with the copy constructor or with the
initialization using =? You're trying to initialize a stud with 5. But
there is no constructor that takes an int or something that int can be
converted to.

stud s(5);

would fail with the same message. Try the following code:

class stud
{
// deliberately make the copy constructor private, so it's inaccessible
stud(const stud&) {}
public:
stud(int) {}
};

int main()
{
stud s = stud(5);
}
Not sure how, the call "stud s=stud(5);" would call a copy constructor.

As I wrote, stud(5) creates a temporary stud object and initializes with
with 5. It needs something like a stud(int) constructor to do this. Then, s
is created from that temporary, and for that, the copy constructor is used.
Then, the temporary is destroyed.
It should not. Let me know if I am wrong..

You are.
 
K

Karl Heinz Buchegger

Jaspreet said:
#include <iostream>

using namespace std;

class stud
{
public:
stud (stud &s)
{
cout<<endl<<"copy";
}
stud(int a)
{
cout<<endl<<"1-arg constructore";
}
};
int main()
{
stud s=stud (5);
return (EXIT_SUCCESS);
}

[snip]

Not sure how, the call "stud s=stud(5);" would call a copy constructor.
It should not. Let me know if I am wrong..

You are wrong

The sequence of events in

stud s = stud(5);

is:

create a temporary stud object and initialize it with 5 using
the stud::stud(5) constructor.

create the object s and initialize it with the previously generated
temporary object. For this the copy constructor is used (since this
is object creation. An assignment is never used for object initialization,
even if you write '=')

Your program failes because a temporary cannot be bound to a reference which
is not const. Now look at your 'copy constructor':
stud (stud &s)
{
cout<<endl<<"copy";
}

It takes the argument by reference. But this reference is not const. Thus the
temporary cannot be bound to it and hence the compilation fails.


stud s = stud(5);

is equivalent to

stud s ( stud(5) );

Don't confuse yourself. Even if you write '=', this is *not* an assignment.
This is the construction of a new object and for that *always* a constructor
is used. (Assignment would require that the object existed previously, but this
is an object under construction, thus assigment cannot be used)
 
J

Jaspreet

Karl said:
Jaspreet said:
#include <iostream>

using namespace std;

class stud
{
public:
stud (stud &s)
{
cout<<endl<<"copy";
}
stud(int a)
{
cout<<endl<<"1-arg constructore";
}
};
int main()
{
stud s=stud (5);
return (EXIT_SUCCESS);
}

[snip]

Not sure how, the call "stud s=stud(5);" would call a copy constructor.
It should not. Let me know if I am wrong..

You are wrong

The sequence of events in

stud s = stud(5);

is:

create a temporary stud object and initialize it with 5 using
the stud::stud(5) constructor.

create the object s and initialize it with the previously generated
temporary object. For this the copy constructor is used (since this
is object creation. An assignment is never used for object initialization,
even if you write '=')

Your program failes because a temporary cannot be bound to a reference which
is not const. Now look at your 'copy constructor':
stud (stud &s)
{
cout<<endl<<"copy";
}

It takes the argument by reference. But this reference is not const. Thus the
temporary cannot be bound to it and hence the compilation fails.


stud s = stud(5);

is equivalent to

stud s ( stud(5) );

Don't confuse yourself. Even if you write '=', this is *not* an assignment.
This is the construction of a new object and for that *always* a constructor
is used. (Assignment would require that the object existed previously, but this
is an object under construction, thus assigment cannot be used)

Hi

Yes I know that is not assignment. I apologise for dragging it more,
but consider the following code:

#include <iostream>
using namespace std;

class stud
{
};
int main()
{
stud s=stud (5); //this should fail
return (EXIT_SUCCESS);
}

According to me, "stud s=stud (5);" should fail and should never try to
call a copy constructor. While compiling the code, compiler (gcc 3.2.2)
complains:
obj.cc: In function `int main()':
obj.cc:10: no matching function for call to `stud::stud(int)'
obj.cc:6: candidates are: stud::stud()
obj.cc:6: stud::stud(const stud&)

If that call had been successful then it should have called the copy
constructor which is created by c++ for us, but it gives the above
error messages. Let me know what I am missing.

Thanks!! and have a nice day!!
 
K

Krishanu Debnath

Jaspreet wrote:

[snip]

Hi

Yes I know that is not assignment. I apologise for dragging it more,
but consider the following code:

#include <iostream>
using namespace std;

class stud
{
};
int main()
{
stud s=stud (5); //this should fail
return (EXIT_SUCCESS);
}

According to me, "stud s=stud (5);" should fail and should never try to
call a copy constructor. While compiling the code, compiler (gcc 3.2.2)

It must have been tried to call the copy constructor(unless compiler
optimize it away as mentioned by Rolf Magnus), if you had supplied a
constructor like .. stud::stud(int).
complains:
obj.cc: In function `int main()':
obj.cc:10: no matching function for call to `stud::stud(int)'
obj.cc:6: candidates are: stud::stud()
obj.cc:6: stud::stud(const stud&)

If that call had been successful then it should have called the copy
constructor which is created by c++ for us, but it gives the above
error messages. Let me know what I am missing.

Thanks!! and have a nice day!!

Krishanu
 
K

Karl Heinz Buchegger

Jaspreet said:
Hi

Yes I know that is not assignment. I apologise for dragging it more,
but consider the following code:

#include <iostream>
using namespace std;

class stud
{
};
int main()
{
stud s=stud (5); //this should fail
return (EXIT_SUCCESS);
}

According to me, "stud s=stud (5);" should fail and should never try to
call a copy constructor. While compiling the code, compiler (gcc 3.2.2)
complains:
obj.cc: In function `int main()':
obj.cc:10: no matching function for call to `stud::stud(int)'
obj.cc:6: candidates are: stud::stud()
obj.cc:6: stud::stud(const stud&)

If that call had been successful then it should have called the copy
constructor which is created by c++ for us, but it gives the above
error messages. Let me know what I am missing.

What's unclear about that?

What is the compiler telling you?
It tells you:
obj.cc: In function `int main()':
obj.cc:10: no matching function for call to `stud::stud(int)'

"Hey buddy, I was looking for a constructor that takes an int as an argument.
But I could not find one, because ....
obj.cc:6: candidates are: stud::stud()
obj.cc:6: stud::stud(const stud&)

... I found only those 2: The default constructor and the copy constructor
But no constructor taking an int."

The compiler is not complaining about the copy constructor. It is complaining
about the missing constructor which takes an int.

The copy constructor has nothing to do with the error message (other then
that g++ lists it as one constructor which it tried, but could not use for
creating the temporary object).

Just in case you missed it, again: In

stud s=stud (5);

there are *2* constructors called!
One for creating the temporary object. The second for initializing
the object s from that temporary.

This time your example fails, because the first part (creating the temporary)
cannot be done.
 
J

Jaspreet

Karl Heinz Buchegger wrote:
[snip]
Just in case you missed it, again: In

stud s=stud (5);

there are *2* constructors called!
One for creating the temporary object. The second for initializing
the object s from that temporary.

This time your example fails, because the first part (creating the temporary)
cannot be done.

Thanks Karl. I should have got this before. Apologies for being a drag
on this.

Thanks!! and have a nice day!!
Jaspreet
 

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

No members online now.

Forum statistics

Threads
473,787
Messages
2,569,629
Members
45,330
Latest member
AlvaStingl

Latest Threads

Top