<iostream> //added
<conio.h> //added
<vcl.h>
#pragma
hdrstop
#pragma
argsused
template <typename T>
class Holder {
 private:
   T* ptr;    // refers to the object it holds (if any)

 public:
   // default constructor: let the holder refer to nothing
   Holder() : ptr(0) {  cout << " Holder() called" << endl; /*★*/
   }

   // constructor for a pointer: let the holder refer to where the pointer refers
   /*explicit*/ Holder (T* p) : ptr(p) {  cout << " Holder (T* p) called" << endl;/*★*/
   }

   // destructor: releases the object to which it refers (if any)
   ~Holder() {
       delete ptr;
       cout << " ~Holder() called" << endl; /*★*/
       getch(); /*★*/
   }

   // assignment of new pointer
   // 代入の両辺が同一の検査は不要(理由。下記関数がprivate
   //        Holder<T>& operator= (Holder<T> const&);
   Holder<T>& operator= (T* p) {
       delete ptr;
       ptr = p;
       return *this;
   }

   // pointer operators
   T& operator* () const { 
       return *ptr;
   }

   T* operator-> () const {
       return ptr; 
   }

   // get referenced object (if any) 
   T* get() const {
       return ptr;
   }

   // release ownership of referenced object
   // 目的はownershipをなくすことだけ。objectを破棄することではない。
   void release() {
       ptr = 0;
   }

   // exchange ownership with other holder
   void exchange_with (Holder<T>& h) {
       swap(ptr,h.ptr);
   }

   // exchange ownership with other pointer
   void exchange_with (T*& p) {
       swap(ptr,p);
   }

 private:
   // no copying and copy assignment allowed  
   // Holderはownershipが排他的だから、外で使えないようにする
   Holder (Holder<T> const&); //★mainにおける[C++ エラー]時、本行をcomment化
   Holder<T>& operator= (Holder<T> const&); //★mainにおける[C++ エラー]時、本行をcomment化
};

class Something {
 public:
   void perform() const {
   std::cout << "perform() called." << endl;
   }
};

void do_two_things()
{
   Holder<Something> first(new Something);
   first->perform();

   Holder<Something> second(new Something);
   second->perform();
}

struct S {
  int a;
  float b;
};

int main(int argc, char* argv[])
{
   int *pI = new int(123);
   cout << " pI=" << pI << endl;
   cout << " *pI=" << *pI << endl;

   cout << "_1" << endl;
   Holder<int> pH(new int(42));
   //Holder<int> pH = new int(42); //[C++ エラー]'Holder<int>::Holder(const Holder<int> &)' はアクセスできない
                                   //privateの Holder (Holder<T> const&); をコメントにすれば実行可能
   cout << " pH=" << pH.get() << endl;
   cout << " *pH=" << *pH << endl;

   Holder<int> qH;
   cout << " qH=" << qH.get() <<endl;

   Holder<int> rH(pI);
   cout << " rH=" << rH.get() <<endl;
   cout << " *rH=" << *rH << endl;

   //Holder<int> sH(pH); //ERROR:private部分見よ[C++ エラー] 'Holder<int>::Holder(const Holder<int> &)' はアクセスできない
                         //privateの Holder (Holder<T> const&); をコメントにすれば実行可能
   //pH = rH;            //ERROR:private部分見よ[C++ エラー] 'Holder<int>::operator =(const Holder<int> &)' はアクセスできない
                         //privateの operator =(Holder<T> const&); をコメントにすれば実行可能
   //pH = pH;            //ERROR:private部分見よ[C++ エラー] 'Holder<int>::operator =(const Holder<int> &)' はアクセスできない

   cout << "_2" << endl;
   pH.exchange_with(qH);  // exchange_withは、他の型とも可能
   cout << " pH=" << pH.get() << " qH=" << qH.get() <<endl;
   cout << " *qH=" << *qH <<  endl;

   cout << "_3" << endl;
   pH = pI;               //左辺 Holder<int>型、右辺 int*型
   cout << " pH=" << pH.get() << " pI=" << pI <<endl;
   cout << " *pH=" << *pH << " *pI=" << *pI << endl;

   cout << "_4" << endl;
   //pI = pH;               //ERROR: 左辺 int*型、右辺 Holder<int>型
                          //[C++ エラー]'Holder<int>' 型は 'int *' 型に変換できない
   cout << "_5" << endl;
   pH.release(); //ownershipをなくす。object破棄してない。
   cout << " pH=" << pH.get() <<endl;

   cout << "_6" << endl;
   do_two_things();

   cout << "_7" << endl;
   delete pI;
   cout << "_8" << endl;

   Holder<S> pS(new S);
   pS->a = 10;
   pS->b = 3.14;

   cout << "_9" << endl;
   getch();
   return 0;
}
最終更新:2006年07月24日 17:33