⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chap2.lst

📁 The Art of C++一书的配套源代码
💻 LST
📖 第 1 页 / 共 2 页
字号:
    cout << "After collecting for shutdown() for "  
         << typeid(T).name() << "\n";    
  #endif  
}

listing 2
#include <iostream> 
#include <new> 
#include "gc.h" 
 
using namespace std; 
 
int main() { 
  GCPtr<int> p; 
 
  try { 
    p = new int; 
  } catch(bad_alloc exc) { 
    cout << "Allocation failure!\n"; 
    return 1; 
  } 
 
  *p = 88; 
 
  cout << "Value at p is: " << *p << endl; 
 
  int k = *p; 
 
  cout << "k is " << k << endl; 
   
  return 0; 
}

listing 3
// Show a GCPtr going out of scope prior to the end 
// of the program. 
#include <iostream> 
#include <new> 
#include "gc.h" 
 
using namespace std; 
 
int main() { 
  GCPtr<int> p; 
  GCPtr<int> q; 
 
  try { 
    p = new int(10); 
    q = new int(11); 
 
    cout << "Value at p is: " << *p << endl; 
    cout << "Value at q is: " << *q << endl; 
     
    cout << "Before entering block.\n"; 
 
    // Now, create a local object. 
    { // start a block 
      GCPtr<int> r = new int(12); 
      cout << "Value at r is: " << *r << endl; 
    } // end the block, causing r to go out of scope 
 
    cout << "After exiting block.\n"; 
 
  } catch(bad_alloc exc) { 
    cout << "Allocation failure!\n"; 
    return 1; 
  } 
 
  cout << "Done\n"; 
 
  return 0; 
}

listing 4
// Allocate and discard objects. 
#include <iostream> 
#include <new> 
#include "gc.h" 
 
using namespace std; 
 
int main() { 
  try { 
    // Allocate and discard objects.     
    GCPtr<int> p = new int(1); 
    p = new int(2); 
    p = new int(3); 
    p = new int(4); 
   
    // Manually collect unused objects for 
    // demonstration purposes. 
    GCPtr<int>::collect(); 
 
    cout << "*p: " << *p << endl; 
  } catch(bad_alloc exc) { 
    cout << "Allocation failure!\n"; 
    return 1; 
  } 
 
 
  return 0; 
}

listing 5
// Demonstrate indexing a TCPtr. 
#include <iostream> 
#include <new> 
#include "gc.h" 
 
using namespace std; 
 
int main() { 
 
  try { 
    // Create a GCPtr to an allocted array of 10 ints. 
    GCPtr<int, 10> ap = new int[10]; 
 
    // Give the array some values using array indexing. 
    for(int i=0; i < 10; i++) 
      ap[i] = i; 
 
    // Now, show the contents of the array. 
    for(int i=0; i < 10; i++) 
      cout << ap[i] << " "; 
 
    cout << endl; 
 
  } catch(bad_alloc exc) { 
    cout << "Allocation failure!\n"; 
    return 1; 
  } 
 
 
  return 0; 
}

listing 6
// Demonstrate an iterator. 
#include <iostream> 
#include <new> 
#include "gc.h" 
 
using namespace std; 
 
int main() { 
 
  try { 
    // Create a GCPtr to an allocted array of 10 ints. 
    GCPtr<int, 10> ap = new int[10]; 
 
    // Declare an int iterator. 
    GCPtr<int>::GCiterator itr; 
 
    // Assign itr a pointer to the start of the array. 
    itr = ap.begin();     
 
    // Give the array some values using array indexing. 
    for(unsigned i=0; i < itr.size(); i++) 
      itr[i] = i; 
 
    // Now, cycle through array using the iterator. 
    for(itr = ap.begin(); itr != ap.end(); itr++) 
      cout << *itr << " "; 
 
    cout << endl; 
 
  } catch(bad_alloc exc) { 
    cout << "Allocation failure!\n"; 
    return 1; 
  } catch(OutOfRangeExc exc) { 
    cout << "Out of range access!\n"; 
    return 1; 
  } 
 
 
  return 0; 
}

listing 7
// Use GCPtr with a class type. 
#include <iostream> 
#include <new> 
#include "gc.h" 
 
using namespace std; 
 
class MyClass { 
  int a, b; 
public: 
  double val; 
 
  MyClass() { a = b = 0; } 
 
  MyClass(int x, int y) { 
    a = x; 
    b = y; 
    val = 0.0; 
  } 
 
  ~MyClass() { 
    cout << "Destructing MyClass(" << 
         a << ", " << b << ")\n"; 
  } 
 
  int sum() { 
    return a + b; 
  } 
 
  friend ostream &operator<<(ostream &strm, MyClass &obj); 
}; 
 
// An overloaded inserter to display MyClass. 
ostream &operator<<(ostream &strm, MyClass &obj) { 
  strm << "(" << obj.a << " " << obj.b << ")"; 
  return strm; 
} 
 
int main() { 
  try { 
    GCPtr<MyClass> ob = new MyClass(10, 20); 
 
    // Show value via overloaded insertor. 
    cout << *ob << endl; 
 
    // Change object pointed to by ob. 
    ob = new MyClass(11, 21); 
    cout << *ob << endl; 
 
    // Call a member function through a GCPtr. 
    cout << "Sum is : " << ob->sum() << endl; 
 
    // Assign a value to a class member through a GCPtr. 
    ob->val = 98.6; 
    cout << "ob->val: " << ob->val << endl; 
 
    cout << "ob is now " << *ob << endl; 
  } catch(bad_alloc exc) { 
    cout << "Allocatino error!\n"; 
    return 1; 
  } 
 
  return 0; 
}

listing 8
// Demonstrating GCPtr. 
#include <iostream> 
#include <new> 
#include "gc.h" 
 
using namespace std; 
 
// A simple class for testing GCPtr with class types. 
class MyClass { 
  int a, b; 
public: 
  double val; 
 
  MyClass() { a = b = 0; } 
 
  MyClass(int x, int y) { 
    a = x; 
    b = y; 
    val = 0.0; 
  } 
 
  ~MyClass() { 
    cout << "Destructing MyClass(" << 
         a << ", " << b << ")\n"; 
  } 
 
  int sum() { 
    return a + b; 
  } 
 
  friend ostream &operator<<(ostream &strm, MyClass &obj); 
}; 
 
// Create an insertor for MyClass. 
ostream &operator<<(ostream &strm, MyClass &obj) { 
  strm << "(" << obj.a << " " << obj.b << ")"; 
  return strm; 
} 
 
// Pass a normal pointer to a function. 
void passPtr(int *p) { 
  cout << "Inside passPtr(): " 
       << *p << endl; 
} 
 
// Pass a GCPtr to a function. 
void passGCPtr(GCPtr<int, 0> p) { 
  cout << "Inside passGCPtr(): "  
       << *p << endl; 
} 
 
int main() { 
 
  try { 
    // Delcare an int GCPtr. 
    GCPtr<int> ip; 
 
    // Allocate an int and assign its address to ip. 
    ip = new int(22); 
 
    // Display its value. 
    cout << "Value at *ip: " << *ip << "\n\n"; 
 
    // Pass ip to a function  
    passGCPtr(ip); 
 
    // ip2 is created and then goes out of scope 
    { 
      GCPtr<int> ip2 = ip; 
    } 
 
    int *p = ip; // convert to int * pointer' 
   
    passPtr(p); // pass int * to passPtr()  
 
    *ip = 100; // Assign new value to ip 
 
    // Now, use implicit conversion to int * 
    passPtr(ip); 
    cout << endl; 
 
    // Create a GCPtr to an array of ints 
    GCPtr<int, 5> iap = new int[5]; 
 
    // Initialize dynamic array. 
    for(int i=0; i < 5; i++) 
      iap[i] = i; 
 
    // Display contents of array. 
    cout << "Contents of iap via array indexing.\n"; 
    for(int i=0; i < 5; i++) 
      cout << iap[i] << " "; 
    cout << "\n\n"; 
 
    // Create an int GCiterator. 
    GCPtr<int>::GCiterator itr; 
 
    // Now, use iterator to access dynamic array. 
    cout << "Contents of iap via iterator.\n"; 
    for(itr = iap.begin(); itr != iap.end(); itr++) 
      cout << *itr << " "; 
    cout << "\n\n"; 
 
    // Generate and discard many objects 
    for(int i=0; i < 10; i++) 
      ip = new int(i+10); 
 
    // Now, manually garbage collect GCPtr<int> list. 
    // Keep in mind that GCPtr<int, 5> pointers 
    // will not be collected by this call. 
    cout << "Requesting collection on GCPtr<int> list.\n"; 
    GCPtr<int>::collect(); 
 
    // Now, use GCPtr with class type. 
    GCPtr<MyClass> ob = new MyClass(10, 20); 
 
    // Show value via overloaded insertor. 
    cout << "ob points to " << *ob << endl; 
 
    // Change object pointed to by ob. 
    ob = new MyClass(11, 21); 
    cout << "ob now points to " << *ob << endl; 
 
    // Call a member function through a GCPtr. 
    cout << "Sum is : " << ob->sum() << endl; 
 
    // Assign a value to a class member through a GCPtr. 
    ob->val = 19.21; 
    cout << "ob->val: " << ob->val << "\n\n"; 
 
    cout << "Now work with pointers to class objects.\n"; 
 
    // Declare a GCPtr to a 5-element array 
    // of MyClass objects. 
    GCPtr<MyClass, 5> v; 
 
    // Allocate the array. 
    v = new MyClass[5];  
 
    // Get a MyClass GCiterator. 
    GCPtr<MyClass>::GCiterator mcItr; 
 
    // Initialize the MyClass array. 
    for(int i=0; i<5; i++) { 
      v[i] = MyClass(i, 2*i); 
    } 
 
    // Display contents of MyClass array using indexing. 
    cout << "Cycle through array via array indexing.\n"; 
    for(int i=0; i<5; i++) { 
      cout << v[i] << " "; 
    } 
    cout << "\n\n"; 
 
    // Display contents of MyClass array using iterator. 
    cout << "Cycle through array through an iterator.\n"; 
    for(mcItr = v.begin(); mcItr != v.end(); mcItr++) { 
      cout << *mcItr << " "; 
    } 
    cout << "\n\n"; 
 
    // Here is another way write the preceding loop. 
    cout << "Cycle through array using a while loop.\n"; 
    mcItr = v.begin(); 
    while(mcItr != v.end()) { 
      cout << *mcItr << " "; 
      mcItr++; 
    } 
    cout << "\n\n"; 
 
    cout << "mcItr points to an array that is " 
         <<  mcItr.size() << " objects long.\n"; 
 
    // Find number of elements between two iterators. 
    GCPtr<MyClass>::GCiterator mcItr2 = v.end()-2; 
    mcItr = v.begin(); 
    cout << "The difference between mcItr2 and mcItr is " 
         << mcItr2 - mcItr; 
    cout << "\n\n"; 
 
    // Can also cycle through loop like this. 
    cout << "Dynamically compute length of array.\n"; 
    mcItr = v.begin(); 
    mcItr2 = v.end(); 
    for(int i=0; i < mcItr2 - mcItr; i++) { 
      cout << v[i] << " "; 
    } 
    cout << "\n\n"; 
 
  
    // Now, display the array backwards. 
    cout << "Cycle through array backwards.\n"; 
    for(mcItr = v.end()-1; mcItr >= v.begin(); mcItr--) 
      cout << *mcItr << " "; 
    cout << "\n\n"; 
 
    // Of course, can use "normal" pointer to 
    // cycle through array. 
    cout << "Cycle through array using 'normal' pointer\n"; 
    MyClass *ptr = v; 
    for(int i=0; i < 5; i++) 
      cout << *ptr++ << " "; 
    cout << "\n\n"; 
 
    // Can access members through a GCiterator. 
    cout << "Access class members through an iterator.\n"; 
    for(mcItr = v.begin(); mcItr != v.end(); mcItr++) { 
      cout << mcItr->sum() << " "; 
    } 
    cout << "\n\n"; 
 
    // Can allocate and delete a pointer to a GCPtr 
    // normally, just like any other pointer. 
    cout << "Use a pointer to a GCPtr.\n"; 
    GCPtr<int> *pp = new GCPtr<int>(); 
    *pp = new int(100); 
    cout << "Value at **pp is: " << **pp; 
    cout << "\n\n"; 
 
    // Because pp is not a garbage collected pointer, 
    // it must be deleted manually. 
    delete pp;  
  } catch(bad_alloc exc) { 
    // A real application could attempt to free 
    // memory by collect() when an allocation 
    // error occurs.  
    cout << "Allocation error.\n"; 
  } 
 
  return 0; 
}

listing 9
// Load test GCPtr by creating and discarding 
// thousands of objects. 
#include <iostream> 
#include <new> 
#include <limits> 
#include "gc.h" 
 
using namespace std; 
 
// A simple class for load testing GCPtr. 
class LoadTest { 
  int a, b; 
public: 
  double n[100000]; // just to take up memory 
  double val; 
 
  LoadTest() { a = b = 0; } 
 
  LoadTest(int x, int y) { 
    a = x; 
    b = y; 
    val = 0.0; 
  } 
 
  friend ostream &operator<<(ostream &strm, LoadTest &obj); 
}; 
 
// Create an insertor for LoadTest. 
ostream &operator<<(ostream &strm, LoadTest &obj) { 
  strm << "(" << obj.a << " " << obj.b << ")"; 
  return strm; 
} 
 
int main() { 
  GCPtr<LoadTest> mp; 
  int i; 
 
  for(i = 1; i < 20000; i++) { 
    try { 
      mp = new LoadTest(i, i); 
    } catch(bad_alloc xa) { 
      // When an allocation error occurs, recycle 
      // garbage by calling collect(). 
      cout << "Last object: " << *mp << endl; 
      cout << "Length of gclist before calling collect(): " 
           << mp.gclistSize() << endl; 
      GCPtr<LoadTest>::collect(); 
      cout << "Length after calling collect(): " 
           << mp.gclistSize() << endl; 
    } 
  } 
   
  return 0; 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -