Jump to content
  • Advertisement
Sign in to follow this  
CoB_ChrizZz

is this an assignment or constructor call ? it behaves as if it is both

This topic is 2501 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, i got trouble to understand the following call in the main():
a =20;


class X {
private:
int data;
public:
~X()
{
cout << "Destruktor " << data << '\n';
}
X(int d = -1) : data(d)
{
cout << "Allgemeiner Konstruktor " << data << '\n';
}
X(const X &x) : data(x.data)
{
cout << "Kopierkonstruktor " << data << '\n';
}
X& operator=(const X& x) //nimmt auch Konstanten (wie in etwa 20)
{
data = x.data;
cout << "Zuweisungsoperator " << data << '\n';
return *this;
}
void set(int d)
{
data = d;
}
int get()
{
return data;
}
};

X a(0);

int main()
{
cout << '\n' << "Start main" << '\n';
X a; // Allgemeiner Konstruktor -1
a =20;
// Allgemeiner Konstruktor 20
// Zuweisungsoperator 20
// Destruktor 20


char g;
cin >> g;
return 0;
}


basicly a = 20 should be an assignment by using the assignment operator.
But it also works without the assignment operator.
It would just print out:
Allgemeiner Konstruktor 20
Destruktor 20

instead.

So what happens here ? can't the compiler decide wether ist is an assignment or a constructor call ?
why is this ?
and why is there an destructor call ? it's definetely not because it reaches the end of the programm..because it still awaits "cin >> f"

Share this post


Link to post
Share on other sites
Advertisement
For the destructor call, maybe it detects that you are not going to use the variable anymore, and thus destroys it before reaching the end of the block.

Share this post


Link to post
Share on other sites
You don't have an operator=() defined that takes an int, so the compiler is having to create an X instance from the int, and assign a to that.

EDIT: And Waterlimon is correct about the destructot call - it's the temporary X instance being destroyed.

Share this post


Link to post
Share on other sites
This is called "conversion by constructor" in the language standard.

Here is the example they use in the language standard


struct X {
X(int);
X(const char*, int =0);
};
void f(X arg) {
X a = 1; // a = X(1)
X b = "Jessie"; // b = X("Jessie",0)
a = 2; // a = X(2)
f(3); // f(X(3))
}

Share this post


Link to post
Share on other sites
Thank you guys but i still have some uqestions ^^;

The compiler creates automaticly a constructor with 20 as value AND then assigns 20 to it, which doesn't change anything at all ?
I mean i would understand if the compiler would create a new instance of X with -1 as default parameter and then assign 20 to it.

And what makes "a" temporary ? it doesn't run out of scope but is destroyed ? i never saw this beahaviour before. Does this depend on the c++ compiler i am using ?
or is this a determined thing even before runtime ?

sorry for my noobish question but i have an important test on friday and i really wanna understand things more in depth :/

thank you very much !

Share this post


Link to post
Share on other sites
If it helps to clear up your confusion, the code is equivalent to this:
[source]
X a;
a = X(20);
[/source]
It is not a that is destroyed, but the temporary value X(20) that has to be created in ordet to perform the assignment to a.

What happens is:

  1. Default-construct the named variable a.
  2. Construct a temporary object from the integer 20.
  3. Assign the temporary object to the named variable a.
  4. Destroy the temporary object.

Step 2 is what causes the program to print that the constructor with value 20 is called.
Step 4 is what causes the program to print that the destructor is called.

Share this post


Link to post
Share on other sites
super, thank you Brother Bob. That cleared my whole confusion about this issue !!! :)

and thanks to all the other guys again who basicly said the same but i misinterpreted the thing about the temporary variable ;)

Share this post


Link to post
Share on other sites
If you change your constructor declaration to:

explicit X(int d = -1) : data(d)


You won't get the confusing automatic type conversions. You have to manually call the constructor if you want them.

Share this post


Link to post
Share on other sites
For the destructor call, maybe it detects that you are not going to use the variable anymore, and thus destroys it before reaching the end of the block.


The compiler can do that? Doesn't that essentially break RAII? For example, how could std::scope_lock work if the compiler could do this?

Share this post


Link to post
Share on other sites

[quote name='Waterlimon' timestamp='1328624848' post='4910504'] For the destructor call, maybe it detects that you are not going to use the variable anymore, and thus destroys it before reaching the end of the block.


The compiler can do that? Doesn't that essentially break RAII? For example, how could std::scope_lock work if the compiler could do this?
[/quote]
It cannot.

As with any compiler optimization, the compiler can only optimize code as long as the observable behavior of the code does not change. If the compiler can destroy an object earlier without any side effects, then I don't know of any reason why it should not be able to do so. Now, since the destructor in the OP's code, and in RAII in general since you mentioned it, has side effects (OP's code is outputting text, and RAII typically release a resource), it cannot be performed earlier since that would change the observable behavior of the program.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!