临时对象研究手记

类别:VC语言 点击:0 评论:0 推荐:

  临时对象,在C++表层和内部实施非常至多.
  然而由于它特定的性质,很多行为不为人所知.
  在Andrei发起的编译时编程中,它是很有价值的东东....
  下面我们通过实验来求证一些行为,
  以便更好的利用它:

#include <iostream>
#include <stdio.h>

using namespace std;

class x;
void fook__(x _in);

class x{
public:
x(int _param):m_Idata(_param){}
~x() { cout<<" I am des ..now.."<<" "<<m_Idata<<endl; }
void print(){ cout<<" Signal..."<<endl; }
public:
int m_Idata;
};

void fook(x _in)
{
_in.print();
cout<<" "<<_in.m_Idata<<endl;
}

void fook_()
{
x(100);
fook__(x(1200));
}

void fook__(x _in)
{
_in.print();
x(1000).print();
}

int main(){

//++++++++++++++++++++++++++
int _Idata;
cout<<" "<<&_Idata<<endl;
cout<<" "<<&x(10)<<endl;

//+++++++++++++++++++++++

{
  x(10);   // [1]
};

//+++++++++++++++++++++++

{
x a(199);
};
//+++++++++++++++++++++++

cout<<"------------------------"<<endl;

//+++++++++++++++++++++++

fook_();                  //这个地方很重要

//++++++++++++++++++++++

cout<<"-----------------------"<<endl;

//+++++++++++++++++++++++

x(10);     // [2]

//+++++++++++++++++++++++
cout<<"----------------------"<<endl;

fook(x(100));  //[3]

//+++++++++++++++++++++++
//
// 从上面可看出:
//         1.“即时的”临时对象(对比于copy等性质的)的生命期到(;)为止...
//         2.在涉及临时对象的一切[物和事,无论这些物和事深入多少层,
//           或者某一步之后变毫无关系和作用......]
//           结束,原临时对象(上面的函数传入是copy的)才会销毁.
//           而“即时的”临时对象的生命期是最短的...............
//                                                    
// 我对这种现象的看法:
//           1. 编译器识别临时对象,并像对待普通变量一样为它分配空间,
//              然而在编译期,编译器了解它所有的行为和数据被使用情况
//              在特定时机,调用析构...但是这里的析构不是堆对象那种
//              意义,它不会继续调用::operator delete(,)来实行所谓的
//              释放空间,那事实上也"没用"那只对堆对象有效...这样
//              即使调用了析构,你看到的“意想",析构并不代表一定跟
//              内存有关.
//               对于栈上
//              的临时对象那没必要(如果你的对象不够复杂)....
//              而对于堆上的临时对象,它没有"句柄" ,你永远释放
//              不了它...想管也管不了....
//               那么你建一个,Memory Leak 便重一点........
//               [谨防这种行为.............]
//              除非delete x("I am programming....");
//---------------------------你看看这个片段---------------------------
/*
#include <iostream>
#include <stdio.h>

using namespace std;

class x{
public:
  char* _chr_ptr;
  x(char* _in):_chr_ptr(_in){}
  //
  //  char* _chr_ptr;
  //x(char* _in):_chr_ptr(new char[strlen(_in)+1]){
  //                            strcpy(_chr_ptr,_in);
  //}
  //                再试一试这个...........[2]
  //
  ~x(){ delete _chr_ptr;   //注意这个地方 ,在连接栈上的数据时,没作用
   cout<<_chr_ptr<<endl;   //而连接堆上的数据时,此处会有问题.
   cout<<this<<endl;       //注意
  }
};

int main(){
x("I am programming...");  //注意这个临时对象
getchar();              //如果你使用new x("I am programming...")
return 1;               //会出问题的......再组合[2],再试一试...
                        //你试一试: new x("I am programming....")和
                        //       delete x("I am programmin......")    
}
*/
//              
//              你回头,,,,,再想象建立在栈上的对象......
//
//+++++++++++++++++++++++
//
//        总结:一切云开雾散,只是编译器是怎样怎样控制临时对象交错时的
//               生命期管理,依然求索......
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


getchar();
return 1;
}


----------------------------------------------------------------------
                    不要认为分析这个没什么价值
                    请看一精致的程式:
                    临时对象解决多线程的问题
               ----------------------------------------
          programme1:
          class Widget
          {
           ...
           void Lock();  //进入临界区
           void Unlock(); //退出临界区
           //这个地方的临界建立,须利用系统函数,简略之.....
          };
       
          programme2:
          template <class T>
          class LockingProxy
          {
            public:
            LockingProxy(T* pObj) : pointee_ (pObj)
            { pointee_->Lock(); }
            //    在临时对象构造是就锁定
            //    weight对象(临界区).
            ~LockingProxy() { pointee_->Unlock(); }
            //           
            //   在临时对象销毁时,退出临界区.
            //
            T* operator->() const
            { return pointee_; }
            //
            //  这里重载->运算符.将对临时对象的方法执行
            //  请求转交给weight对象
            //
            private:
            LockingProxy& operator=(const LockingProxy&);
            T* pointee_;
         };

         programme3:
         template <class T>
         class SmartPtr
         {
            ...
            LockingProxy<T> operator->() const
            { return LockingProxy<T>(pointee_); }
            //
            //  核心就在这里:产生临时对象
            //  LockingProxy<T>(pointee_)
            private:  sT* pointee_;
         };

         Programme4.
         SmartPtr<Widget> sp = ...;
         sp->DoSomething();       //##1
--------------------------------------------
 
   事实上,很多地方的临时对象是值得发掘的...
   譬如:const x fook(const x& _in);
         cout<<x.function<<enld;
   关键在于临时对象生命期和生命期交错的管理.

------------------------------------------------------------------- 
               声明:上面的是本人通过程式实验的结果
                      有问题或知之甚详者,
                      请教:[email protected]
------------------------------------------------------------------

本文地址:http://com.8s8s.com/it/it1892.htm