Questions about how arguments are passed in C ++

So, I'm a pretty experienced C programmer who needs a lot of C ++ programming. There are some subtleties regarding a language that I never felt confident in. For example, the best methods for passing arguments.

Suppose, for example, that I have a class with a black box Object (it can have many member variables for everyone we know) and a function fn that takes an instance vector of Object as an argument. It seems to me that there are four main ways to convey this:

void fn(vector<Object> vec); void fn(vector<Object*> vec); void fn(vector<Object> *vec); void fn(vector<Object> &vec); 

And, of course, we could also use some combination of these functions.

I want to make sure that I have this directly:

Method 1 must copy a vector class that includes a copy of each instance of the object in the vector. This could potentially be a huge overload and therefore bad.

(this one I'm not sure) Method 2 copied all the variables of the vec method, but it would only copy the addresses of each instance of the object. I don’t know enough about what is contained in the vector class to find out whether it is advisable or not.

Methods 3 and 4 are quite simple and similar to each other and introduce minimal overhead.

Is this all right? and what is the preferred method, bearing in mind that we know nothing about the object?

+4
source share
4 answers

The preferred way to pass an argument would be void fn(const vector<Object> &vec);
Of course, you do not change it. Using pointers, as in cases 2 and 3, is usually not a good practice in C ++.
Now version 1:
void fn(vector<Object> vec);
It is generally considered bad because it makes a copy, but sometimes it is necessary. Keep in mind that sometimes the compiler can optimize a copy using copy elision in the case of temporary ones and if the copy does not change (but in this case you should use const ref)

+3
source

This is all right. Method 2 would really make a copy of vec, and since its elements are pointers to Object , they only copy these pointers, not the actual objects. This is not very different from passing pointers to an Object in an array.

As a rule, the presence of pointer vectors is disapproving. When the vector goes beyond the scope of these pointers will not be deleted automatically. You would definitely have to delete them yourself. And if you still have a memory leak, if your code throws an exception at any time before that.

If the objects are small, you should use a vector of objects, not pointers. If the objects are large, you should use a smart pointer vector.

+1
source

Everything you say is true.

If you are going to copy the vector inside the function anyway, or if you want to change the vec inside fn but not change the original copy, use # 1. Then you can save the copy inside and let the compiler (possibly) make a copy for you.

If you want to change the original vector (from outside fn ), use # 4.

If you don't want to change the vector at all, use # 4 with const :

 void fn(const vector<Object> &vec); 

Do not use # 2 because it is very difficult for you to place a pointer on a vector. The memory must be new d and delete d, and it will be error prone. [Mandatory note shared_ptr].

Your # 3 is not idiomatic C ++. This is fine, but idiomatic C ++ avoids pointers in favor of references in this case.

+1
source

In principle, you understood this correctly, while others gave a good answer and comments. I just want to add two comments:

1) If you have

 std::vector<Object> v; 

then obviously you cannot call fn(v) to overload void fn(vector<Object*> vec); .

2) You said:

"I don’t know enough about what is contained in a vector class" ...

The most popular implementations of std::vector contain only three pointers as data elements, and the cost of copying these three pointers is very low. However, this is not what happens when copying std::vector (this would be if its copy constructor were generated by the compiler). In fact, std::vector has a copy constructor that (as you said) copies all the elements of the original std::vector . It is also associated with memory allocation and can be a very expensive operation.

0
source

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


All Articles