C++ Tutorial/Data Types/reference

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

Assign value to a reference-return

#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 
}
99.1

Change reference value

#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;
}
5
99

class for counted reference semantics

/* 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.
 */
#include <iostream>
#include <list>
#include <deque>
#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;
}
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

#include <iostream>
#include <string>
#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;
}

Creating and Using References

#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;
 }
intValue: 5
intReference: 5
intValue: 7
intReference: 7

Reassigning a reference

#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;
 }
intValue:       5
intReference:   5
&intValue:      0x22ff74
&intReference:  0x22ff74
intValue:       8
intTwo: 8
intReference:   8
&intValue:      0x22ff74
&intTwo:        0x22ff6c
&intReference:  0x22ff74

References must be initialized

#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; 
}
x = 321    y = 321
x = 123    y = 123

Return a reference to an array element.

#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 
}
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

#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 
}
100
100

Use an independent reference.

#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; 
}
10 10
121

Use reference as a return type

#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];
}
2
4
6
0

Use References operator &

#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;
}
intValue: 5
intReference: 5
&intValue: 0x22ff74
&intReference: 0x22ff74

Use reference to swap value

#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;
}
2  1