临时对象,在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;
关键在于临时对象生命期和生命期交错的管理.
-------------------------------------------------------------------
声明:上面的是本人通过程式实验的结果
有问题或知之甚详者,
------------------------------------------------------------------