临时对象研究手记

原创 2003年03月27日 11:03:00

  临时对象,在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;
   关键在于临时对象生命期和生命期交错的管理.

------------------------------------------------------------------- 
               声明:上面的是本人通过程式实验的结果
                      有问题或知之甚详者,
                      请教:81_redstar@163.com
------------------------------------------------------------------

“变速齿轮”研究手记

注意:如果你看了本文,对我们这个软件有兴趣,请到我们的主页www.vrbrothers.com下载。注:为节省篇幅,本文对一些计算机术语直接使用而没有作详细的解释,读者若有不熟悉之处,建议参考清华大学...
  • rchu
  • rchu
  • 2001年03月05日 18:24
  • 1569

[转]VCL窗口函数注册机制研究手记,兼与MFC比较

    我们知道Windows平台上的GUI程序都必须遵循Windows的消息响应机制,可以简单概括如下,所有的窗口控件都向系统注册自身的窗口函数,运行期间消息可被指派至特定窗口控件的窗口函数处理。对...
  • nhczp
  • nhczp
  • 2007年03月17日 16:19
  • 1107

对C++临时对象的内存位置的研究

首先,这是一个很少有人研究的问题:C++的临时对象是在堆里还是在栈里的。 但若不研究清楚内部原理,每次产生临时量时都会纠结于此, 网上能找到的资料也都是new在堆里、定义在函数内部就是栈里,或者是临时...
  • kingpharaoh
  • kingpharaoh
  • 2015年08月20日 14:42
  • 669

Delphi 中 COM 实现研究手记(一)

前言     前些日子用 Delphi 写了一个 Windows 外壳扩展程序,大家知道 Windows 外壳扩展实际上就是 COM 的一种应用 -- Shell COM,虽然整个程序写得还算比较顺利...
  • procedure1984
  • procedure1984
  • 2009年02月18日 18:27
  • 1176

探讨“临时对象”(temporary object)

MSDN中对VS2012版本的临时对象的说明如下:     在某些情况下,编译器有必要产生临时对象。     当初始化一个常量引用(const reference)时,如果给定的初始化对象...
  • zssureqh
  • zssureqh
  • 2012年07月01日 19:30
  • 2993

C++中临时对象的产生与优化

C++中临时对象的产生与优化 本文主要介绍c++中临时对象产生的几种情况,同时介绍避免的策略。由于在C++中对象的创建和消除会调用该对象对应的构造和析构函数,是一个相对比较耗时的操作,从程序效率角度来...
  • fangqingan_java
  • fangqingan_java
  • 2013年07月13日 20:55
  • 1227

C++临时对象那些事儿

C++大概是这个世界上最飘逸、成功、失败的语言吧,临时对象是C++语言中最复杂的东西之一。 以下代码段新手大概经常会写吧: std::string FetchFormat(){ return "%d...
  • wind_2008_06_29
  • wind_2008_06_29
  • 2016年04月13日 16:55
  • 1495

函数的返回值和临时对象的问题

在函数的声明时,其实是最重要的一步,如何设计一个好的接口(用户友好),直接决定了后面的编码工作是否能够行云流水。先给出整体架构,检查各类和接口之间的逻辑有没有问题。...
  • JiajieZhuo
  • JiajieZhuo
  • 2016年12月26日 20:52
  • 1032

《IT项目经理成长手记》读后有所思

最近看了一本潘东、韩秋泉先生合著的一本书《IT项目经理成长手记》,虽然与IT项目经理相关的书我看的不多,对于这个行业了解也不算太多,但是我依然认为这是一本很值得想要从事互联网产品、通信行业解决方案管理...
  • u013816144
  • u013816144
  • 2016年06月20日 21:53
  • 3883

[随手记经验] 【转载】其实你不懂记账

这些问题你都能立马回答出来吗?  1、你的资产负债率是多少?  2、你的收支结余比例是多少?  3、上个月结余的钱都放在什么地方了?  4、目前你手上有多少可动用资金?  5、你的股票、基金等投资收益...
  • fishmai
  • fishmai
  • 2016年09月01日 12:58
  • 1169
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:临时对象研究手记
举报原因:
原因补充:

(最多只允许输入30个字)