参数传递(reference parameter)

Programmers who come to C++ from a C background are used to passing pointers to obtain access to the argument. In C++ it, is safer and more natural to use reference parameters.

It should be obvious that a function that takes a plain, nonconst reference may not be called on behalf of a const object. After all, the function might change the object it is passed and thus violate the const ness of the argument. What may be less obvisous is that we also cannot call such a function with an rvalue or with an object of a type that requires a conversion:

// function takes a non-const reference parameter
int incr(int &val)
{
     return ++val;
}
int main()
{
     short v1 = 0;
     const int v2 = 42;
     int v3 = incr(v1); // error: v1 is not an int
     v3 = incr(v2); // error: v2 is const
     v3 = incr(0); // error: literals are not lvalues
     v3 = incr(v1 + v2); // error: addition doesn't yield an lvalue
     int v4 = incr(v3); // ok: v3 is a non const object type int
}

Parameters that do not change the value of the corresponding argument should be const references.

// returns index of first occurrence of c in s or s.size() if c isn't in s
// Note: s doesn't change, so it should be a reference to const
string::size_type find_char(string &s, char c)
{
      string::size_type i = 0;
      while (i != s.size() && s[i] != c)
            ++i;                    // not found, look at next character
      return i;
}

This function takes its string argument as a plain (nonconst) reference, even though it doesn't modify that parameter. One problem with this definition is that we cannot call it on a character string literal:

if (find_char("Hello World", 'o')) // ...

Best practices:Reference parameters that are not changed should be references to const . Plain, nonconst reference parameters are less flexible. Such parameters may not be initialized by const objects, or by arguments that are literals or expressions that yield rvalues.

int *&v1;    // v1 is a reference to a pointer to an object of type int .

 

In order to avoid copying the vector , we might think that we'd make the parameter a reference. In practice, C++ programmers tend to pass containers by passing iterators to the elements we want to process:

// pass iterators to the first and one past the last element to print
void print(vector<int>::const_iterator beg,
vector<int>::const_iterator end)
{
      while (beg != end) {
            cout << *beg++;
      if (beg != end) cout << " "; // no space after last element
      }
      cout << endl;
}

 

posted on 2014-04-22 19:56  江在路上2  阅读(237)  评论(0编辑  收藏  举报