Classes and rules

Pages: 12
To summarize, for the majority of programs we needn't pointers either smart or raw, because of stack.
Nah, pointers are not only used for memory but inheritance, extending life time, sharing, etc.

and between them only smart ones and mostly unique_ptr
The use of unique_ptr is very limited. Thus it's rather difficult to deal with it (without resorting to raw pointer).

I still can't comprehend what makes that statement to call the move assignment and not the copy assignment.
On line 3 a temporary object of rule_of_five is created. A temporary object is used by to default as a moveable object when available. Since move assignment is available it is used accordingly.

so why do we need that = default yet?
When no constructor is defined you do not need = default. As soon as you define a constructor certain other constructors (like base_of_five_defaults()) are not available anymore. You can bring them back into play with = default.
Does it mean that when we have two objects on both sides of an assignment operator, =, when the right-hand one is temporary, the move assignment is called not the copy assignment, and the temp object will be moved to the left-hand object?

I got the second part too.
Thank you.
And to reach a conclusion:

If we have a class with some data members, we must initialize them by a constructor, once we instantiate the class somewhere in the code. And for the rest of methods, we either declare and define them manually or use =default so that the compiler does it for us automatically.

In case our class hasn't any data members, we leave everything by default, "rule-of-zero".

Are these both correct please?
Does it mean that when we have two objects on both sides of an assignment operator, =, when the right-hand one is temporary, the move assignment is called not the copy assignment, and the temp object will be moved to the left-hand object?
Yes. For instance:
1
2
3
4
5
6
7
8
std::vector<int> foo()
{
  std::vector<int> result;
  do_something_with_result;
  return result;
}
...
std::vector<int> bar = foo(); // move assignment, not copy 


If we have a class with some data members, we must initialize them by a constructor, once we instantiate the class somewhere in the code.
Data members can be initialized without constructor. See:

https://en.cppreference.com/w/cpp/language/data_members

Thus you need only a constructor when providing data on instantiation.

And for the rest of methods, we either declare and define them manually or use =default so that the compiler does it for us automatically.
Only for special member functions. See:

https://en.cppreference.com/w/cpp/language/member_functions#Special_member_functions
Cppreference is nearly always confusing for me. I believe it's but for C++ experts. But I got the issue to some extent. Thanks.

One tiny spot I didn't figure out is in: (the latter link above)

1
2
3
4
5
6
// lvalue-only assignment operator
    D& operator=(D other) & {
        std::swap(other.data, data);
        std::swap(other.data2, data2);
        return *this;
    }


What's or what does & do in "D& operator=(D other) & {" ?
That's somewhat astonishing for me for the time being.

Also, does this a rule from C++, or the compiler, please?

1
2
3
4
5
6
7
8
std::vector<int> foo()
{
  std::vector<int> result;
  do_something_with_result;
  return result;
}
...
std::vector<int> bar = foo(); // move assignment, not copy  


Also, why move assignment and not move constructor?
Last edited on
What's or what does & do

the answer is in the line above: "// lvalue-only assignment operator" and also a few lines lower
1
2
   d2 = d1; // OK: assignment to lvalue
//   D(5) = d1; // ERROR: no suitable overload of operator= 
. It makes it so that assignment operator can only be called on lvalues.
more at https://en.cppreference.com/w/cpp/language/member_functions#const-.2C_volatile-.2C_and_ref-qualified_member_functions

does this a rule from C++, or the compiler, please?

for how return statement automatically moves from local variables, see https://en.cppreference.com/w/cpp/language/return#Notes
Last edited on
Also, why move assignment and not move constructor?
Indeed, the move constructor is called in that context.
@Cubbi,

I didn't get my answer from cppreference. To be honest, I never use that website for gaining info about C++ because for a simple issue it adds as many other sophisticated items as possible making the whole issue extremely bewildering.
I guess the instruction for that move constructor is a rule of C++ not the interference of the compiler.

And for the &, not clear yet! It's I think the first time I see that character after a parenthesis. So I can't understand it.






Last edited on
for a simple issue it adds as many other sophisticated items as possible

It actually does the opposite: it removes as many other sophisticated items as possible, while still remaining a reference (that is, correct and complete) and not turning into a tutorial: its audience are working programmers, not students. To be fair, the cppreference note on return's auto-move feature is hard to follow even though it omitted some detail. I just reformatted it for easier reading if that helps.

All the thing related to the issue I discovered there is this:
first as if expression were an rvalue expression (thus it may select the move constructor)

So, the move constructor is "probably" selected, otherwise control may fall into an infinite loop causing the stack overflow error message.

So, it goes to be up to the compiler to the the safest decision for us which is the move constructor.
Topic archived. No new replies allowed.
Pages: 12