指针和引用的区别

来源:互联网 发布:网络模拟大乐透摇奖机 编辑:程序博客网 时间:2024/03/28 20:15

单件模式,像所有的同志一样我也在用,不过不幸的是我走上了
        歧途。鉴于对社会强烈地责任感(吐),我认为有必要做个简要
        的总结来避免后人步我的后尘(狂吐)。
        那么现在开始写正式的悔过书。
首先,首先清一下嗓子,哈哈。
再次,酝酿一下感情。
最后,再清一下嗓子,OK,THATS ALL,^_^.
        所有有正义感的人都在向我扔鼠标,有的人开始搬起显示器。好
        ,好,在这种躁动下,不利于我诚心接受犯下的滔天错误,请大
        家少安毋躁,请看下下面的代码:
        template <typename T> class Singleton
{
protected: 
      static  T* ms_Singleton;
        public:
        Singleton( void )
        {
        assert( !ms_Singleton );
        ms_Singleton = static_cast<T*>(this);
        }
        ~Singleton( void )
        { assert( ms_Singleton ); ms_Singleton = 0; }
        static T& getSingleton( void )
        { assert( ms_Singleton ); return (
        *ms_Singleton ); }
        static T* getSingletonPtr( void )
        { return ( ms_Singleton ); }
};
非常明显,这段代码是无懈可击的,嘿嘿。出品人( Paul D
        Turner)。
那么看看我糟糕的表现:
class Application: public Singleton<Application>
{
        public:
        static Application* getSingletonPtr();
        static Application getSingletonP();
void Run();
        }
明眼人一眼就看出了端倪,我犯了个超级错误,那就是
Application getSingletonPtr();
这是致命的缺陷,直接导致了单件模式的失败,这样的写法首先
        语法上是说的过去的,但事实上我并没有重载
Application& getSingleton();所以当我在别的类中用
Application::getSingleton()时出现了让我眼前发黑的一暮。
        因为当程序刚刚跳出调用这个方法的方法时(like that:
void ClassRoot::RunApplication
{
        Application::getSingleton().Run();
}

,Application的析构函数被调用,结果可想而知,Application
        中的所有的资源都被释放。接着系统无情的扔出一个面目可憎的
        窗体,对我进行了最为严厉的批评,这个批评直接导致了你在此
        消磨时间。特别声名,由此对你青春的耽搁,从刑法上讲,我不
        会负主要责任,^_^.
“这是为什么”,我问了同样的问题而且不只“千百遍”。我只
        是没有用引用而已,是的,引用,这的确是个问题。就象用指针
        一样,引用也是没有问题地。前面程序失败的原因是有新的临时
        Application实例产生,当运行完RunApplication时,临时对象
        被释放,他调用了析构函数,不幸的是,我在他里面释放了一些
        指针和资源,错误产生了,他是如此的自然和顺理成章。
引用,指针,我想有必要看看他们的猫腻所在。
        LOOK一下下面的代码:
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
        class ouyang2008
{
        public:
        int a;
        int b;
        ouyang2008(){a=0;b=0;}
        ~ouyang2008(){}
        void printtext()
        {
        //cout<<a<         }
};
        int _tmain(int argc, _TCHAR* argv[])
{
        ouyang2008* pObj=new ouyang2008;
        //cout<         ouyang2008& obj=*pObj;
        ouyang2008* p=&obj;
        delete pObj;
        cout<         return 0;
}
        现在我们注意的焦点在:
        ouyang2008& obj=*pObj;
        ouyang2008* p=&obj;
看看他们有什么不同,那么我们怎么LOOK呢?WIN32 ASM,
        yes,it is that:
        ouyang2008& obj=*pObj;
00411556 mov eax,dword ptr [ebp-14h]
00411559 mov dword ptr [ebp-20h],eax
        ouyang2008* p=&obj;
0041155C mov eax,dword ptr [ebp-20h]
0041155F mov dword ptr [ebp-2Ch],eax
哦,ALL is here ,so it is org.
从汇编上来看,他们没有任何区别,他们都在函数的堆栈中保存
        了一个对象的指针,所以当退出函数时只是释放了指针而已,对
        对象没有任何影响。
现在我们可以讲:
对机器来说他们没有任何区别。
对使用者来讲,咳、咳、咳,我不得不很无奈的重复别人所说的
“引用是安全的”。
        为什么是安全的?
第一,你不用担心释放的问题。
第二呢,你不会很惊讶地看着让你胆战心惊的“EXCEPTION
        ASSETT ERROR ox0000005 access invalidate”.
运行以下下面的代码:
#include "stdafx.h"
#include #include <iostream>
using namespace std;
        class ouyang2008
{
        public:
        int* a;
        int* b;
        ouyang2008(){a=new int[1];b= new int[1];}
        ~ouyang2008(){delete[] a;delete[] b;a=b=NULL;}
        void printtext()
        {
        cout<<*a<         }
};
        int _tmain(int argc, _TCHAR* argv[])
{
        ouyang2008* pObj=new ouyang2008;
        //cout<         ouyang2008& obj=*pObj;
        ouyang2008* p=&obj;
        delete pObj;
        if (p)//祸根
        {
        p->printtext();
        }
        cout<         return 0;
}
当然如果你现在的工作是对付。NET
你没有必要注意这方面的问题:
曾经有为老兄在。NET还到处是臭虫的时候就这样说过:
“对于。NET来讲,任何类的对象都是在堆中建立的,类的变量
        和对象之间只有引用,如果你在栈中看到了类的对象,那你就是
        见到鬼了,而且是。NET鬼。”
呵呵,THAT IS OVER。
双手合十,企求我不是在胡说八道。
        本文转自
http://www.cppblog.com/flyman/archive/2007/06/28/27166.html  

原创粉丝点击