Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I pass a string by value or pass a pointer to it?

I have a function which looks like this

int myclass::setVersion(std::string ver)
{
  if (ver.size()>1)
  {
    version.swap(ver)
    return 0;
  }
  else 
    return -1;
}

My question is very simple, is it better to pass ver the way it is or better to pass it as a pointer to string? FYI, ver is a small size string (around 8). EDIT: it does not matter if ver is changed. I just want to replace version with the contents of ver. EDIT2: I am using visual studio 2008.

like image 917
Samer Avatar asked Oct 14 '14 14:10

Samer


People also ask

Should I pass by reference or pointer?

The difference between pass-by-reference and pass-by-pointer is that pointers can be NULL or reassigned whereas references cannot. Use pass-by-pointer if NULL is a valid parameter value or if you want to reassign the pointer. Otherwise, use constant or non-constant references to pass arguments.

Is passing by reference faster than pointer?

We take advantage of this small size when storing data and when passing parameters to functions. It's much faster and memory-efficient to copy a pointer than to copy many of the things a pointer is likely to point to. A reference is stored in as many bytes as required to hold an address on the computer.

Should you pass strings by reference C++?

OTOH, for C++98 it is best to pass by reference - less data gets copied around. Passing const or non const depend of whether you need to change the argument or not. Save this answer.

Is pointer the same as pass by value?

The difference between pass-by-pointer and pass-by-value is that modifications made to arguments passed in by pointer in the called function have effect in the calling function, whereas modifications made to arguments passed in by value in the called function can not affect the calling function.


4 Answers

It depends on what you want the behavior of the code to be.

Most of the suggested answers here change the behavior from your posted code in that they will modify the string that's passed in (or make the code fail to compile because it can't modify the passed in argument).

In the example you posted,the string passed to myclass::setVersion() will not be modified (the parameter may be modified, but that is just a copy fo the string passed in; a copy which will be destroyed when the function returns).

For a a case like this, I'd suggest passing a const std::string&:

int myclass::setVersion(std::string const& ver)
{
  if (ver.size()>1)
  {
    version = ver;
    return 0;
  }
  else 
    return -1;
}

This way the copy is made only when necessary.

But honestly, unless the function is called often, it's probably nothing to worry much about.

like image 113
Michael Burr Avatar answered Oct 21 '22 13:10

Michael Burr


In C++11 you can add an overload which accepts rvalue reference:

int myclass::setVersion(std::string& ver);
int myclass::setVersion(std::string&& ver);

This way you'll be able to swap from rvalues as well as lvalues. And actually instead of swap you can perform a move assignment:

version = std::move(ver);

This is potentially faster than swap, depending on std::string implementation.

Examples of usage:

string getVersion() { return "version2"; }

string v1 = "version1";
a.setVersion(v1);           // lvalue
a.setVersion(getVersion()); // rvalue
a.setVersion("version3");   // rvalue as well

Demo

UPDATE: Indeed, you have to have both variants of setVersion for maximum flexibility. But I agree with others in that all this is premature optimization and should be used only if profiling shows a bottleneck at this point.

like image 37
Anton Savin Avatar answered Oct 21 '22 13:10

Anton Savin


Please pass a reference.

int myclass::setVersion(std::string& ver)
like image 3
elimad Avatar answered Oct 21 '22 14:10

elimad


You want to store the contents of ver into version. A copy has to be made, the question is where.

You can do it the way you propose, as swapping is fast. But I notice not all control paths cause the version string to be assigned a new value.

Therefore I suggest the following

int myclass::setVersion(const std::string& ver)
{
  if (ver.size()>1)
  {
    version = ver;
    return 0;
  }
  else 
    return -1;
}

This will avoid a copy should the size of ver be 1, in which case you don't want to copy the string into version.

like image 3
Neil Kirk Avatar answered Oct 21 '22 14:10

Neil Kirk