C++ pointers and references in functions - c++

I am coming from a C#/Java background into C++, using visual studio community 2017 & plenty of tutorials. I came to the point where am unsure of what is a correct way to write a function to process a vector of data. Should I force a function to use a pointer / reference? Should I let compiler sort it out? What is best practice?
This is my main, I ask for an input on vector size, then pass a pointer to the integer value to function that creates and populates vector with values through a simple for loop.
I then pass the array to another function that performs a shuffle.
vector<int> intVector(int* count)
{
vector<int> vi;
for (int i = 1; i <= *count; i++)
vi.push_back(i);
return vi;
}
vector<int> &randVector(vector<int> *v)
{
shuffle(v->begin(), v->end(), default_random_engine());
return *v;
}
int _tmain(int argc, _TCHAR* argv[])
{
int count;
cout << "Enter vector array size: ";
cin >> count; cout << endl;
cout << "Vector of integers: " << endl;
vector<int> vi = intVector(&count);
for_each(vi.begin(), vi.end(), [](int i) {cout << i << " ";});
cout << endl;
vi = randVector(&vi);
cout << "Randomized vector of integers: " << endl;
for_each(vi.begin(), vi.end(), [](int i) {cout << i << " ";});
cout << endl;
return 0;
}
So my question is, what is the best practice in my case to avoid unnecessary copying. Should I even care about it? Should I rely on compiler to solve it for me?
I am planing to use C++ for game development on desktop and consoles. Understanding memory and performance management is important for me.

You are in charge of enforcing (or avoiding) the copy of objects around.
Regarding your example:
You can avoid using pointers and use a reference instead.
Like in the following:
vector<int>& randVector(vector<int>& v)
{
shuffle(v->begin(), v->end(), default_random_engine());
return v;
}
Note that since you are using a reference, the shuffle operation is already modifying the parameter of randVector so there is no real need to return a reference to it.
As a rule of thumb when you need to pass an object around and you want to avoid a potentially expensive copy you can use references:
void function(<const> Object& v)
{
// do_something_with_v
}

The rules on passing in C++ for typical code are pretty straightforward (though obviously still more complex than languages without references/pointers).
In general, prefer references to pointers, unless passing in null is actually something you might do
Prefer to write functions that don't mutate their inputs, and return an output by value
Inputs should be passed by const reference, unless it is a primitive type like an integer, which should be passed by value
If you need to mutate data in place, pass it by non-const reference
See https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rf-conventional for more details.
The upshot of this is that here are the "correct" signatures for your two functions:
vector<int> intVector(int count);
void randVector(vector<int> &v);
This doesn't take into account iterators which is probably really the correct "generic" way to write the second function but that is a bit more advanced. But, see std::shuffle which lets you randomize any arbitrary container by leveraging iterators: http://en.cppreference.com/w/cpp/algorithm/random_shuffle.
Since you mentioned unnecessary copying, I will mention that when you return things like vector by value, they should never be copied (I'm assuming you're using C++11 or newer). They will instead be "moved", which doesn't have significant overhead. Thus, in newer C++ code, "out parameters" (passing in arguments by reference to mutate them) is significantly discouraged compared to older versions. Good to know in case you encounter dated advice. However, passing in by reference for something like shuffling or sorting is considered an "in/out" parameter: you want to mutate it in place and the existing data is important, not simply being overwritten.

Related

C++ Custom Stack Printing Issues

I am creating a custom class Stack to store a couple string variables. When I attempt to print the stack, it says that the stack is always empty, which is not correct. I am using vectors to represent the custom stack, so the way I go about my print method should work, but for some reason it does not. What is my error? Is it in my isEmpty method?
void stack::printStack() {
std::vector<std::string> v;
if(stack::isEmpty()) {
std::cout << "Stack is empty! " << std::endl;
}
else {
for(int i = 0; i != v.size(); i++) {
std::cout << v[i] << std::endl;
}
}
}
You are returning a copy of the underlying vector with
std::vector<std::string> stack::getVector();
This results in all calls such as stack::getVector().push_back(n); making no modifications to the stack::v, but modifying the returned temporary instead.
I don't see, why you shouldn't be using v directly in the member functions:
v.push_back(n);
Or, if you don't want to do that (for some reason), make getVector return both reference-to-const and reference-to-non-const:
std::vector<std::string> const& stack::getVector() const { return v; };
std::vector<std::string> &stack::getVector() { return v; };
Note, that you're breaking encapsulation with std::vector<std::string> & returning overload.
You are creating a local variable here:
void stack::printStack(){
std::vector<std::string> v;
That v is not the same as the v member variable. That local v is empty, thus your loop never prints.
Also, use descriptive variable names. Using a single letter variable name such as v is not a good idea.
Also, with respect to return a vector by reference or copy, see this question and answer: Returning vector copies.
So do you want to return a copy of the vector, or do you want to return the actual vector? If it is the latter, return a reference, if it's the former, then return a copy (as your current code is doing). Note that there are implications in returning a copy as opposed to returning a reference (as the link shows).

C++ iterate an array of integers whose size is unknown?

I have the following array:
int* myArray = new int[45];
If I wanted to iterate each element without knowing the actual size of the array, I would need to use a for_each?
If so, then how would you write the for_each? I was looking over the following site and reading up on for_each but can't figure out how to put this together.
http://www.cplusplus.com/reference/algorithm/for_each/
Update: A for_each is not a good choice in this case, due to the fact that the size of the array has to be known. vectors are the proper way to accomplish such task. My reason for using arrays, in this case, was for learning purposes. if this was a serious project I would move to something such as Lists/Vectors.
Note when the question was first posted, the array in question was declared as
int myArray[45];
This answer deals with that particular case.
If you have C++11 support, you can use a range based loop:
for (int& i : myArray) {
std::cout << i << "\n";
}
C++11 also provides std::begin and std::end, which you can use with a fixed size array to obtain iterators:
std::for_each(std::begin(myArray), std::end(myArray), <func>);
Another option, which works for C++03 and you are dealing with fixed size arrays, is to define a function template:
// taken a fixed size array by reference and loop over it
template <typename T, unsigned int N>
void array_for_each( T (&a)[N]) {
for (unsigned int i = 0; i < N; ++i) {
// do something with array elements
std::cout << a[i] << " ";
}
}
int main() {
int a[5];
array_for_each(a);
}
If you use MSVC (Microsoft Visual C++), you can use "for each."
for each(int i in arr) {
cout << i << ' ' << endl;
}
NOTE: This only works in the block of code the array is declared in.
If not, you can also use the new range-based for loop in the C++11 standard.
for(int i : arr) {
cout << i << ' ' << endl;
}
If you're intent upon the std::for_each:
for_each(arr,arr + 10,[] (int i) {
cout << i << ' ' << endl;
});
NOTE: This requires knowledge of the size of the array (in this example, 10).
You could use a for_each. In this case, you have allocated space for 45 elements in your array, but since it is NULL, you'd probably get a segfault if you tried to do anything. You either need to hold a value of the array, or use something like sizeof(myArray)/sizeof(myArray[0]) (which has its own problems).
Anyway, for a for_each here, if we actually had 45 elements:
std::for_each(myArray, myArray + 45, <func>);
Anyway, this is part of the reason to use vectors: .begin() and .end() reduces errors with using incorrect indexing.
You have described an array of int, not a class that implements a InputIterator, which is what the for_each is designed for, even though you can use it to iterate an array, but you need to know the size of the array to iterate it.
If you want to use for_each you need to use a vector, list, or implement a class that keeps track of the number of elements it contains. IMO it is much easier to just use a vector
If you want to just iterate your current array, assuming it is 0 terminated:
for(int *value = myArray; *value != 0; ++value)
printf("%d\n", *value);
Or, you can use indexes:
for(int index = 0; myArray[index] != 0; ++index)
printf("%d\n", myArray[index]);
IMO the pointer method is cleaner.
This code is still dangerous though, you should either keep track of the number of records in a seperate variable, or use a vector.

sending back a vector from a function

How to translate properly the following Java code to C++?
Vector v;
v = getLargeVector();
...
Vector getLargeVector() {
Vector v2 = new Vector();
// fill v2
return v2;
}
So here v is a reference. The function creates a new Vector object and returns a reference to it. Nice and clean.
However, let's see the following C++ mirror-translation:
vector<int> v;
v = getLargeVector();
...
vector<int> getLargeVector() {
vector<int> v2;
// fill v2
return v2;
}
Now v is a vector object, and if I understand correctly, v = getLargeVector() will copy all the elements from the vector returned by the function to v, which can be expensive. Furthermore, v2 is created on the stack and returning it will result in another copy (but as I know modern compilers can optimize it out).
Currently this is what I do:
vector<int> v;
getLargeVector(v);
...
void getLargeVector(vector<int>& vec) {
// fill vec
}
But I don't find it an elegant solution.
So my question is: what is the best practice to do it (by avoiding unnecessary copy operations)? If possible, I'd like to avoid normal pointers. I've never used smart pointers so far, I don't know if they could help here.
Most C++ compilers implement return value optimization which means you can efficiently return a class from a function without the overhead of copying all the objects.
I would also recommend that you write:
vector<int> v(getLargeVector());
So that you copy construct the object instead of default construct and then operator assign to it.
void getLargeVector(vector<int>& vec) {
// fill the vector
}
Is a better approach for now. With c++0x , the problem with the first approach would go by making use of move operations instead copy operations.
RVO can be relied upon to make this code simple to write, but relying RVO can also bite you. RVO is a compiler-dependent feature, but more importantly an RVO-capable compiler can disable RVO depending on the code itself. For example, if you were to write:
MyBigObject Gimme(bool condition)
{
if( condition )
return MyBigObject( oneSetOfValues );
else
return MyBigObject( anotherSetOfValues );
}
...then even an RVO-capable compiler won't be able to optimize here. There are many other conditions under which the compiler won't be able to optimize, and so by my reckoning any code that by design relies on RVO for performance or functionality smells.
If you buy in to the idea that one function should have one job (I only sorta do), then your dilema as to how to return a populated vector becomes much simpler when you realize that your code is broken at the design level. Your function really does two jobs: it instantiates the vector, then it fills it in. Even with all this pedantary aside, however, a more generic & reliable solution exists than to rely on RVO. Simply write a function that populates an arbitrary vector. For example:
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
template<typename Iter> Iter PopulateVector(Iter it, size_t howMany)
{
for( size_t n = 0; n < howMany; ++n )
{
*(it++) = n;
}
return it;
}
int main()
{
vector<int> ints;
PopulateVector(back_inserter(ints), 42);
cout << "The vector has " << ints.size() << " elements" << endl << "and they are..." << endl;
copy(ints.begin(), ints.end(), ostream_iterator<int>(cout, " "));
cout << endl << endl;
static const size_t numOtherInts = 42;
int otherInts[numOtherInts] = {0};
PopulateVector(&otherInts[0], numOtherInts);
cout << "The other vector has " << numOtherInts << " elements" << endl << "and they are..." << endl;
copy(&otherInts[0], &otherInts[numOtherInts], ostream_iterator<int>(cout, " "));
return 0;
}
Why would you like to avoid normal pointers? Is it because you don't want to worry about memory management, or is it because you are not familiar with pointer syntax?
If you don't want to worry about memory management, then a smart pointer is the best approach. If you are uncomfortable with pointer syntax, then use references.
You have the best solution. Pass by reference is the way to handle that situation.
Sounds like you could do this with a class... but this could be unnecessary.
#include <vector>
using std::vector;
class MySpecialArray
{
vector<int> v;
public:
MySpecialArray()
{
//fill v
}
vector<int> const * getLargeVector()
{
return &v;
}
};

C++ STL - iterate through everything in a sequence

I have a sequence, e.g
std::vector< Foo > someVariable;
and I want a loop which iterates through everything in it.
I could do this:
for (int i=0;i<someVariable.size();i++) {
blah(someVariable[i].x,someVariable[i].y);
woop(someVariable[i].z);
}
or I could do this:
for (std::vector< Foo >::iterator i=someVariable.begin(); i!=someVariable.end(); i++) {
blah(i->x,i->y);
woop(i->z);
}
Both these seem to involve quite a bit of repetition / excessive typing. In an ideal language I'd like to be able to do something like this:
for (i in someVariable) {
blah(i->x,i->y);
woop(i->z);
}
It seems like iterating through everything in a sequence would be an incredibly common operation. Is there a way to do it in which the code isn't twice as long as it should have to be?
You could use for_each from the standard library. You could pass a functor or a function to it. The solution I like is BOOST_FOREACH, which is just like foreach in other languages. C+0x is gonna have one btw.
For example:
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/foreach.hpp>
#define foreach BOOST_FOREACH
void print(int v)
{
std::cout << v << std::endl;
}
int main()
{
std::vector<int> array;
for(int i = 0; i < 100; ++i)
{
array.push_back(i);
}
std::for_each(array.begin(), array.end(), print); // using STL
foreach(int v, array) // using Boost
{
std::cout << v << std::endl;
}
}
Not counting BOOST_FOREACH which AraK already suggested, you have the following two options in C++ today:
void function(Foo& arg){
blah(arg.x, arg.y);
woop(arg.z);
}
std::for_each(someVariable.begin(), someVariable.end(), function);
struct functor {
void operator()(Foo& arg){
blah(arg.x, arg.y);
woop(arg.z);
}
};
std::for_each(someVariable.begin(), someVariable.end(), functor());
Both require you to specify the "body" of the loop elsewhere, either as a function or as a functor (a class which overloads operator()). That might be a good thing (if you need to do the same thing in multiple loops, you only have to define the function once), but it can be a bit tedious too. The function version may be a bit less efficient, because the compiler is generally unable to inline the function call. (A function pointer is passed as the third argument, and the compiler has to do some more detailed analysis to determine which function it points to)
The functor version is basically zero overhead. Because an object of type functor is passed to for_each, the compiler knows exactly which function to call: functor::operator(), and so it can be trivially inlined and will be just as efficient as your original loop.
C++0x will introduce lambda expressions which make a third form possible.
std::for_each(someVariable.begin(), someVariable.end(), [](Foo& arg){
blah(arg.x, arg.y);
woop(arg.z);
});
Finally, it will also introduce a range-based for loop:
for(Foo& arg : my_someVariable)
{
blah(arg.x, arg.y);
woop(arg.z);
}
So if you've got access to a compiler which supports subsets of C++0x, you might be able to use one or both of the last forms. Otherwise, the idiomatic solution (without using Boost) is to use for_eachlike in one of the two first examples.
By the way, MSVS 2008 has a "for each" C++ keyword. Look at How to: Iterate Over STL Collection with for each.
int main() {
int retval = 0;
vector<int> col(3);
col[0] = 10;
col[1] = 20;
col[2] = 30;
for each( const int& c in col )
retval += c;
cout << "retval: " << retval << endl;
}
Prefer algorithm calls to hand-written loops
There are three reasons:
1) Efficiency: Algorithms are often more efficient than the loops programmers produce
2) Correctness: Writing loops is more subject to errors than is calling algorithms.
3) Maintainability: Algorithm calls often yield code that is clearer and more
straightforward than the corresponding explicit loops.
Prefer almost every other algorithm to for_each()
There are two reasons:
for_each is extremely general, telling you nothing about what's really being done, just that you're doing something to all the items in a sequence.
A more specialized algorithm will often be simpler and more direct
Consider, an example from an earlier reply:
void print(int v)
{
std::cout << v << std::endl;
}
// ...
std::for_each(array.begin(), array.end(), print); // using STL
Using std::copy instead, that whole thing turns into:
std::copy(array.begin(), array.end(), std::ostream_iterator(std::cout, "\n"));
"struct functor {
void operator()(Foo& arg){
blah(arg.x, arg.y);
woop(arg.z);
}
};
std::for_each(someVariable.begin(), someVariable.end(), functor());"
I think approaches like these are often needlessly baroque for a simple problem.
do i=1,N
call blah( X(i),Y(i) )
call woop( Z(i) )
end do
is perfectly clear, even if it's 40 years old (and not C++, obviously).
If the container is always a vector (STL name), I see nothing wrong with an index and nothing wrong with calling that index an integer.
In practice, often one needs to iterate over multiple containers of the same size simultaneously and peel off a datum from each, and do something with the lot of them. In that situation, especially, why not use the index?
As far as SSS's points #2 and #3 above, I'd say it could be so for complex cases, but often iterating 1...N is often as simple and clear as anything else.
If you had to explain the algorithm on the whiteboard, could you do it faster with, or without, using 'i'? I think if your meatspace explanation is clearer with the index, use it in codespace.
Save the heavy C++ firepower for the hard targets.

Passing a list of numbers to a function in C++ without building array first?

I'm trying to build a function that accepts an array in the following manner:
int inCommon = findCommon({54,56,2,10}, 4);
int findCommon(int nums[], int len){
for(int i=0; i<len; i++) cout<<nums[i]<<endl;
return 1;
}
Note, that's not actually what my function does, but I do loop through the array. I'm just trying to determine if it's possible to pass an array like {54,56,2,10} instead of having to create an array and pass it? (like this:
int theArray[]= {54,56,2,10};
int inCommon = findCommon(theArray,4);
This is not possible at the time. However, in the next C++ standard C++0x, this will be done using initalizer lists:
int findCommon(std::initializer_list<int> nums)
{
std::initializer_list<int>::iterator it;
for (it = nums.begin() ; it != nums.end() ; ++it)
{
std::cout << *it << std::endl;
}
return 1;
}
See this presentation from Bjarne Stroustrup, and this article from Wikipedia
If you want to try C++0x features, you can check the last versions of gcc, that supports some of them.
You need C++0x!
http://en.wikipedia.org/wiki/C%2B%2B0x#Initializer_lists
No, I believe {} may only be used to initialize an array.
You can do what you want to do using variable argument lists.
no. It is impossible.
But you can create something like template T* arrayCreator(...) function which will create your array,
Or array wrapper with constructor with unspecified arguments count.
Or create object which will have overloaded operator coma or << and will create your array, findCommon( arrCreator() << 1 << 2 << 3 << 5, other parammeters ) - this method more type safe
Or waiting C++0x implementation.