C ++ bandwidth with non primitive types?

I should have a fundamental misunderstanding regarding C ++ 11. My professors told me that it is impossible to pass a non-primitive type of function except for a reference or pointer. However, the following code works just fine

#include <iostream> using namespace std; class MyClass { public: int field1; }; void print_string(string s) { cout << s << endl; } void print_myclass(MyClass c) { cout << c.field1 << endl; } int main(int argc, char *argv[]) { string mystr("this is my string"); print_string(mystr); // works MyClass m; m.field1=9; print_myclass(m); return 0; } 

Running the program gives the next exit

 this is my string 9 RUN SUCCESSFUL (total time: 67ms) 

I am using MinGW / g ++ on Win7

Why does it work? I thought that non-primitive types cannot be passed by value ?!

+4
source share
3 answers

Non-primitive types can certainly be passed by value. (This is described in section 5.2.2 [expr.call] C ++ Standard.)

However, there are several reasons why this is often discouraging, especially in C ++ 03 code.

Firstly, for large objects this is less efficient (compared to passing by reference), because the data is transferred on the stack. The link will take one word on the stack, so passing any object through the stack that is more than one word will be necessarily slower.

Secondly, passing by value calls the copy constructor (or, as @templatetypedef points out, potentially a move constructor in C ++ 11). This additional processing may entail certain overhead.

Thirdly, you may have intended to modify the passed object, but by passing it in a copy (by value), any changes you make to the function will not affect the original object. Therefore, it is important to choose the right semantics (that is, whether you want to change the original). Therefore, this is a potential mistake in some circumstances.

Finally, if there is a poorly written class without a copy constructor or assignment operator, the compiler will automatically generate a default for you. This will execute a shallow copy, which can cause problems such as memory leaks. This is another good reason why it is important to implement these special methods. Full details are provided in this article:

In general, for C ++ 03 code, you usually go through the const& link if you do not intend to modify the object or the normal & link if you need to modify the object. Use a pointer if the parameter is optional.

These questions also contain some good answers and discussions, especially a discussion of the semantics of movement:

The full answer for C ++ 11 is more complicated:

Probably the best summary of which approach to use:

+5
source

Your professor is simply mistaken, maybe he was thinking about JAVA or C #? Everything is passed by value in C ++. To transfer something by reference, you need to pass it using a modifier.

+2
source

Non-primitive types can indeed be passed by value in C ++. If you try to do this, C ++ will use a special function called the copy constructor (or in some cases in C ++ 11, the move constructor) to initialize the parameter as a copy of the argument. Writing copy constructors and assignment operators, as you know, is a difficult part of C ++ (the incorrect becomes easy and becomes correct, so it may happen that professors tried to dissuade you from this. Failure to write a copy constructor or do it wrong can easily lead to program crashes and is a common source of confusion for new C ++ programmers.

I would suggest doing a Google search for the β€œC ++ Rule of 3” or β€œcopy constructor assignment operator” to learn more about how to write functions that copy objects intelligently. It takes a little to speed up how to do it, but once you realize that it's not that difficult.

Hope this helps!

+1
source

Source: https://habr.com/ru/post/1498099/


All Articles