2

In this code :

    class iop {
    public:
        iop(int y) {
            printf("OK\n");
        }

        iop() {
            printf("NO\n");
        }
    };

    int main()
    {
  line 1-   iop o;
  line 2-   o = 8;
  line 3-   return 0;
    }

My conclusion of the way this C++ code work with is:

  1. Create an object of iop class (o) using the default parameterless constructor.

  2. Create an rvalue object of iop class using the constructor with parameter (int) and using the overloaded operator (operator = (iop&&)) to assign it to the object (o) then call the destructor of that rvalue.

  3. Call the destructor of the object (o).

Is my conclusion correct?

Edit This code also compiled

class iop {
public:
    iop(int y) {
        printf("OK\n");
    }

    iop() {
        printf("NO\n");
    }
};

int main()
{
    iop o(5);
    o = 8;
    return 0;
}
output :
OK
OK

That is mean two object are created (o) and one is temporary and the operator= assigen (o) with the temporary object that its constractor argument is 8

f877576
  • 447
  • 2
  • 7
  • 1
    No, it is not correct and a thought experiment should make it obvious that it's not correct. Just focus on `o = 8;` and ask yourself: how is it possible? There is no assignment operator for `=` that takes an `int` parameter, to assign it to `iop`, so how does this compile. You will then reach the conclusion that at least two objects must be constructed here, not one. – Sam Varshavchik Dec 06 '21 at 00:37
  • Unrelated, it is called a *destructor*, not distractor. Related, a fine google-fu term right about now would be "converting constructor" . It's important to your conundrum, and is mentioned in several questions on this site, [including this one here](https://stackoverflow.com/questions/15077466/what-is-a-converting-constructor-in-c-what-is-it-for). – WhozCraig Dec 06 '21 at 00:48
  • "using the overloaded operator (operator = (iop&&)) to create an rvalue object" -- this is incorrect. `operator=` does not create anything. This is an assignment operator. It assigns something that was already created, in some form or fashion. – Sam Varshavchik Dec 06 '21 at 00:52
  • No, only parameters that get passed by value are effectively copied. Parameters that get passed by reference, by definition, are not copied. This includes rvalue references. – Sam Varshavchik Dec 06 '21 at 01:26
  • I edited the post Can you take a look and then tell me if my conclusion is totally correct? @Sam Varshavchik – f877576 Dec 06 '21 at 21:28
  • I thought in this line ( line number two ) o = 8; the temporary object (rvalue) is created by the overloaded operator=(iop&&).but i now know that the temporary object (rvalue) is created in the main function not by the overloaded operator=(iop&&) ( I mean it is created in the scope of main function before calling the overloaded operator(iop&&) ),is this right ? @Sam Varshavchik – f877576 Dec 13 '21 at 02:56
  • Any object, temporary or not, is always created by a constructor, and not by any other operator. C++ does not work this way. All objects get created by a constructor. – Sam Varshavchik Dec 13 '21 at 12:10
  • My two questions are does the temporary object is created in the main function scope ( in my code ) ? and if the overloaded operator takes iop as argument it is mean the operator will call the costructor to create a independent object to the overloaded operator ? @Sam Varshavchik – f877576 Dec 14 '21 at 14:28
  • At this point, I'd like to introduce you to a debugger. Although the answer to your question is fairly straightforward, there is no reason to ask anyone a question that anyone can answer by themselves. This is exactly what a debugger is for. It runs your program, one line at a time, and shows you what's happening. By running the shown code, one step at a time, it's very easy to see when each constructor gets called, from where, and what gets passed to any class method or overloaded operator. Why don't you try to use a debugger, and see with your own eyes what happens? – Sam Varshavchik Dec 14 '21 at 14:47

1 Answers1

4

The class iop has implicitly defined copy and move constructors and assignments.

o = 8;

This will attempt to call operator=. As I've stated the copy and move assignment operators are implicitly defined:

iop& operator=(const iop&);
iop& operator=(iop&&);

Because iop is implicitly constructible from int, both operators are viable, but the move one is preferred as is a perfect match.

So yes, a temporary is created from 8, that is moved into o. At the end of the full expression (at ;) that temporary is destroyed. At the end of main scope o is destroyed.

So your code is more or less equivalent to o = iop{8}.

Sidenote: if you make the int constructor explicit i.e. explicit iop(int y) then o = 8; will no longer compile.

bolov
  • 72,283
  • 15
  • 145
  • 224
  • So the iop& operator=(iop&&); is called not iop& operator=(const iop&); ? @bolov – f877576 Dec 06 '21 at 01:58
  • @f877576 yes indeed – bolov Dec 06 '21 at 01:59
  • I edited the post to answer your Sidenote see the post again @bolov – f877576 Dec 06 '21 at 02:11
  • @f877576 I don't understand. Your edit changes nothing for `o = 8`. – bolov Dec 06 '21 at 02:14
  • you said if i make the constructor explicit then o = 8; will no longer compile. but the code compiles ? @bolov – f877576 Dec 06 '21 at 02:17
  • I edited the post one more time see the post again and i am sorry for bothering you @bolov – f877576 Dec 06 '21 at 02:26
  • I do not understand your sidenote.Can you explain it? and I am sorry for bothering you @bolov – f877576 Dec 06 '21 at 02:41
  • @f877576 https://godbolt.org/z/oW3necYha and see https://stackoverflow.com/questions/121162/what-does-the-explicit-keyword-mean – bolov Dec 06 '21 at 02:43
  • do you mean add the word explicit to the declaration of the constractor? @bolov – f877576 Dec 06 '21 at 02:53
  • @f877576 yes, like in my godbolt example – bolov Dec 06 '21 at 02:55
  • I thought in this line ( line number two ) o = 8; the temporary object (rvalue) is created by the overloaded operator=(iop&&).but i now know that the temporary object (rvalue) is created in the main function not by the overloaded operator=(iop&&) ,is this right @bolov ? – f877576 Dec 06 '21 at 22:41
  • Yes, in the main function. It's not created by the operator or by the main function. It's created by the compiler. – bolov Dec 06 '21 at 23:09
  • I mean it is created in the scope of main function before calling the overloaded operator(iop&&),right?@bolov – f877576 Dec 06 '21 at 23:23
  • @f877576 please consider accepting the answer if it answered your question so that the question doesn't remain unaswered. – bolov Dec 10 '21 at 23:46
  • i am so sorry for bothering you but i am a student and i asked this question again ( I mean it is created in the scope of main function before calling the overloaded operator(iop&&),right? ) because i need a simple answer (yes or no) to write it in notes @bolov – f877576 Dec 11 '21 at 00:50
  • @f877576 as I've said yes. – bolov Dec 11 '21 at 01:18
  • The last thing you said " it is created by the compiler " do you mean ( it is created by the compiler exactly like when i write int v = 9; in the main function the variable that is named v also created by the compiler not by main function ) ? @bolov – f877576 Dec 11 '21 at 02:21
  • @f877576 yes, the implicit operators/constructors are generated by the compiler. The temporary object is created by the compiler. If you want you can say the temporary object is created by the main function, but at the end of the day it doesn't really matter. – bolov Dec 11 '21 at 02:39
  • You wrote in your answer the word " contructible " What is the meaning of this word ? @bolov – f877576 Jun 03 '22 at 02:28
  • It meant "constructible" which means "can be constructed". E.g. see [std::is_constructible](https://en.cppreference.com/w/cpp/types/is_constructible) – bolov Jun 03 '22 at 03:12