C++ Tutorial/Data Types/reference

Материал из C\C++ эксперт
Перейти к: навигация, поиск

Assign value to a reference-return

<source lang="cpp">#include <iostream> using namespace std;

double &f();

double val = 100.0;

int main() {

 double x; 

 f() = 99.1;
 cout << f() << "\n";

 return 0; 

}

double &f() {

 return val; // return reference to val 

}</source>

99.1

Change reference value

<source lang="cpp">#include <iostream.h> main() {

      int a[] = {1,3,5,7,9};
      int i=2 ;
      int &r = a[i];          
      cout <<r<<endl;
      r=99;           
      cout <<a[i]<<endl;
      return 0;

}</source>

5
99

class for counted reference semantics

<source lang="cpp">/* The following code example is taken from the book

* "The C++ Standard Library - A Tutorial and Reference"
* by Nicolai M. Josuttis, Addison-Wesley, 1999
*
* (C) Copyright Nicolai M. Josuttis 1999.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
  1. include <iostream>
  2. include <list>
  3. include <deque>
  4. include <algorithm>

using namespace std; /* class for counted reference semantics

* - deletes the object to which it refers when the last CountedPtr
*   that refers to it is destroyed
*/

template <class T> class CountedPtr {

 private:
   T* ptr;        // pointer to the value
   long* count;   // shared number of owners
 public:
   // initialize pointer with existing pointer
   // - requires that the pointer p is a return value of new
   explicit CountedPtr (T* p=0)
    : ptr(p), count(new long(1)) {
   }
   // copy pointer (one more owner)
   CountedPtr (const CountedPtr<T>& p) throw()
    : ptr(p.ptr), count(p.count) {
       ++*count;
   }
   // destructor (delete value if this was the last owner)
   ~CountedPtr () throw() {
       dispose();
   }
   // assignment (unshare old and share new value)
   CountedPtr<T>& operator= (const CountedPtr<T>& p) throw() {
       if (this != &p) {
           dispose();
           ptr = p.ptr;
           count = p.count;
           ++*count;
       }
       return *this;
   }
   // access the value to which the pointer refers
   T& operator*() const throw() {
       return *ptr;
   }
   T* operator->() const throw() {
       return ptr;
   }
 private:
   void dispose() {
       if (--*count == 0) {
            delete count;
            delete ptr;
       }
   }

};

void printCountedPtr (CountedPtr<int> elem) {

   cout << *elem << " ";

} int main() {

   // array of integers (to share in different containers)
   static int values[] = { 3, 5, 9, 1, 6, 4 };
   // two different collections
   typedef CountedPtr<int> IntPtr;
   deque<IntPtr> coll1;
   list<IntPtr> coll2;
   /* insert shared objects into the collections
    * - same order in coll1
    * - reverse order in coll2
    */
   for (int i=0; i<sizeof(values)/sizeof(values[0]); ++i) {
       IntPtr ptr(new int(values[i]));
       coll1.push_back(ptr);
       coll2.push_front(ptr);
   }
   // print contents of both collections
   for_each (coll1.begin(), coll1.end(),printCountedPtr);
   cout << endl;
   for_each (coll2.begin(), coll2.end(),printCountedPtr);
   cout << endl << endl;
   /* modify values at different places
    * - square third value in coll1
    * - negate first value in coll1
    * - set first value in coll2 to 0
    */
   *coll1[2] *= *coll1[2];
   (**coll1.begin()) *= -1;
   (**coll2.begin()) = 0;
   // print contents of both collections again
   for_each (coll1.begin(), coll1.end(),printCountedPtr);
   cout << endl;
   for_each (coll2.begin(), coll2.end(),printCountedPtr);
   cout << endl;

}</source>

3 5 9 1 6 4
4 6 1 9 5 3
-3 5 81 1 6 0
0 6 1 81 5 -3

constant references

<source lang="cpp">#include <iostream>

  1. include <string>
  2. include <vector>

using namespace std; void display(const vector<string>& inventory); int main() {

   vector<string> inventory;
   inventory.push_back("sword");
   inventory.push_back("armor");
   inventory.push_back("shield");
   display(inventory);
   return 0;

} void display(const vector<string>& vec) {

   cout << "Your items:\n";
   for (vector<string>::const_iterator iter = vec.begin();
        iter != vec.end(); ++iter)
        cout << *iter << endl;

}</source>

Creating and Using References

<source lang="cpp">#include <iostream>

int main()
{
    int  intValue;
    int &intReference = intValue;

    intValue = 5;
    std::cout << "intValue: " << intValue << std::endl;
    std::cout << "intReference: " << intReference << std::endl;

    intReference = 7;
    std::cout << "intValue: " << intValue << std::endl;
    std::cout << "intReference: " << intReference << std::endl;
    return 0;
}</source>
intValue: 5
intReference: 5
intValue: 7
intReference: 7

Reassigning a reference

<source lang="cpp">#include <iostream>

using namespace std; 

int main()
{
    int  intValue;
    int &intReference = intValue;

    intValue = 5;
    cout << "intValue:\t" << intValue << endl;
    cout << "intReference:\t" << intReference << endl;
    cout << "&intValue:\t"  << &intValue << endl;
    cout << "&intReference:\t" << &intReference << endl;

    int intTwo = 8;
    intReference = intTwo;  // not what you think!
    cout << "\nintValue:\t" << intValue << endl;
    cout << "intTwo:\t" << intTwo << endl;
    cout << "intReference:\t" << intReference << endl;
    cout << "&intValue:\t"  << &intValue << endl;
    cout << "&intTwo:\t"  << &intTwo << endl;
    cout << "&intReference:\t" << &intReference << endl;
    return 0;
}</source>
intValue:       5
intReference:   5
&intValue:      0x22ff74
&intReference:  0x22ff74
intValue:       8
intTwo: 8
intReference:   8
&intValue:      0x22ff74
&intTwo:        0x22ff6c
&intReference:  0x22ff74

References must be initialized

<source lang="cpp">#include <iostream> using std::cout; using std::endl; int main() {

  int x = 321;
  int &y = x;
  cout << "x = " << x << "    y = " << y << endl;
  y = 123;
  cout << "x = " << x << "    y = " << y << endl;
  return 0; 

}</source>

x = 321    y = 321
x = 123    y = 123

Return a reference to an array element.

<source lang="cpp">#include <iostream> using namespace std;

double &f(int i); // return a reference

double vals[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };

int main() {

 int i; 

 cout << "Here are the original values: "; 
 for(i=0; i < 5; i++) 
   cout << vals[i] << " "; 

 f(1) = 8.23;   // change 2nd element 
 f(3) = -8.8;   // change 4th element 

 cout << "\nHere are the changed values: \n"; 
 for(i=0; i < 5; i++) 
   cout << vals[i] << " "; 

 return 0; 

}

double &f(int i) {

 return vals[i]; // return a reference to the ith element 

}</source>

Here are the original values: 1.1 2.2 3.3 4.4 5.5
Here are the changed values:
1.1 8.23 3.3 -8.8 5.5

Returning a reference

<source lang="cpp">#include <iostream> using namespace std;

double &f();

double val = 100.0;

int main() {

 double x; 

 cout << f() << "\n"; 

 x = f();           // assign value of val to x 
 cout << x << "\n"; 

 return 0; 

}

double &f() {

 return val; // return reference to val 

}</source>

100
100

Use an independent reference.

<source lang="cpp">#include <iostream> using namespace std;

int main() {

 int j, k; 
 int &i = j;   // independent reference 

 j = 10; 

 cout << j << " " << i; // outputs 10 10 

 k = 121; 
 i = k;      // copies k"s value into j, not k"s address 

 cout << "\n" << j;  // outputs 121 

 return 0; 

}</source>

10 10
121

Use reference as a return type

<source lang="cpp">#include <iostream.h> int& Fn(int * p,int i); main() {

      const int S=4;
      int  a[S] = {1,3,5,-1};
      for (int j = 0; j<S; j++)
      {
              Fn(a,j) += 1;
              cout << Fn(a,j) << endl;
      }
      return 0;

} int& Fn(int * p,int i){

   return p[i];

}</source>

2
4
6
0

Use References operator &

<source lang="cpp">#include <iostream> int main() {

   int  intValue;
   int &intReference = intValue;
   intValue = 5;
   std::cout << "intValue: " << intValue << std::endl;
   std::cout << "intReference: " << intReference << std::endl;
   std::cout << "&intValue: "  << &intValue << std::endl;
   std::cout << "&intReference: " << &intReference << std::endl;
   return 0;

}</source>

intValue: 5
intReference: 5
&intValue: 0x22ff74
&intReference: 0x22ff74

Use reference to swap value

<source lang="cpp">#include <iostream.h> void Swap(int& x,int& y); int main(void) {

      int n1 = 1, n2 = 2;
      Swap(n1,n2);
      cout << n1 << "  " << n2 << endl;

} void Swap(int& x,int& y) {

      int t = x;      x = y;  y = t;

}</source>

2  1