临时对象,在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] ------------------------------------------------------------------

|