-1

I'm beginning with C++ and have some trouble with understanding how to pass std::string as a parameter to functions.

void foo(std::string text)
{
    // ...
}

std::string data = "Hello World!";
foo(data);

In this case, if I'm not wrong, the string value is passed to the function. So whatever I do to the text variable in function foo, it won't have any effect on the data variable.

But how is it possible that to some functions (for examle std::getline) I pass a string in the exact same way and they change its value?

std::string row;
std::getline(std::cin, row);
// now the value of row is changed

Thanks

Martin Heralecký
  • 5,649
  • 3
  • 27
  • 65

4 Answers4

3

In C++ you have a few options:

  1. Pass by value. The function prototype is void foo(std::string text) and you call it with foo(data);. You correctly observe that any modifications made in foo to data are not reflected in the caller. Conceptually a deep copy is taken (a compiler might optimise out the copy if there are no side effects in doing so; but you'd be wise not to rely on that).

  2. Pass by reference. The function prototype is void foo(std::string& text) and you call it with foo(data);. Any modifications made in foo to data are reflected in the caller.

  3. Pass by const reference. The function prototype is void foo(const std::string& text) and you call it foo(data);. This is my favourite: foo is not allowed to modify data: a compile-time error will be issued on such an attempt. Also a deep copy of the string will not be taken.

  4. Pass by pointer. The function prototype is void foo(std::string* text) and you call it foo(&data); foo can modify the string.

  5. Pass by const pointer. The function prototype is void foo(const std::string* text) and you call it foo(&data);. As in (3), foo cannot modify the string passed.

Because the calling syntax for 1 and 2 are identical, some folk dislike passing something that can be modified by reference since it's not obvious to the caller that the parameters could be changed.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
2

Pass it by reference:

void foo(std::string &text)
{
    // ...
}
101010
  • 41,839
  • 11
  • 94
  • 168
2

You have a few options to pass variables in C++

1) By value

void foo(std::string value) { /* ... */ }
// ... call
foo(data);

The copy constructor of std::string is used to create a local instance in foo and modifications stay in the local instance.

2) By reference

void foo(std::string &value) { /* ... */ }
// ... call
foo(data);

The parameter variable is referenced, so value in foo is pointing to the same object that you pass to the function. Changes are reflected in your calling code.

3) By const reference

void foo(const std::string &value) { /* ... */ }
// ... call
foo(data);

As in (2) the parameter object is referenced rather than creating a new instance. However, the contract is not to modify your value inside foo. This may be cheaper in terms of memory and performance than (1) where the whole string is copied.

4) By pointer

void foo(std::string *value) { /* ... */ }
// ... call
foo(&data);

You pass the adress of data as parameter to foo. It is similar to a reference, just relying on pointer logic. In order to access the string in value, you have to dereference the pointer as in (*value) or value->some_string_function()

5) By pointer to constant object

void foo(const std::string *value) { /* ... */ }
// ... call
foo(&data);

Similar to (4), but the object that the pointer is referencing is constant like in the reference case (3). Note that the pointer itself is not constant, so it is possible to point it to a different object. However, the pointer is local (the object pointed to is not local though), so changing the pointer adress inside foo has no effect on the data object.

grek40
  • 13,113
  • 1
  • 24
  • 50
  • Seems Bathsheba was a bit faster typing^^ – grek40 Dec 01 '15 at 08:08
  • But you missed out `const` pointer. Will upvote if you include that. – Bathsheba Dec 01 '15 at 08:14
  • @Bathsheba See, you where faster typing :P. I'm sure there are even more perverted ways (like a const reference to some custom type with a constructor thats taking in a `std::string`) to pass a variable, but thats a different story – grek40 Dec 01 '15 at 08:17
  • @Bathsheba Done, I suppose you are happy now? ;) – grek40 Dec 01 '15 at 09:08
-1

The second argument is an output argument. std::getline(std::cin, row);

ldlchina
  • 927
  • 2
  • 12
  • 31