编程语言

img ZiJinShi

C++中的值参与引用的小问题

发表于2004/9/28 23:04:00  1714人阅读

分类: 1-技术相关

    以前在学校学Pascal的时候,产生了一种习惯性的思维:在函数调用时,如果在函数调用前后,不希望参数的值发生改变,那么使用值参;如果希望发生改变,那么使用形参。
    在C/C++中,不存在形参,都是值传递的,而引用类似于Pascal中的形参。(我不知道这样说是否恰当)。所以,用C++的时候,我就有这种思维方式:在函数调用时,如果在函数调用前后,不希望参数的值发生改变,那么使用值参;如果希望发生改变,那么使用形参引用。
  
    今天的一个偶然的错误,原来我的想法不对。
    问题简化,以下是一个类的定义和实现:

   class CA 
    {
        public:
             CA(char *a_pcChar = "Test");
             virtual ~CA();

        private:
             char *m_pcChar;
    };
  
   
    CA::CA(char *a_pcChar)
    {
             if(a_pcChar == NULL)
            {
                 m_pcChar = NULL;
                 return;
            }
         m_pcChar = new char[256];
         memset(m_pcChar,'/0',sizeof(char) * 256);
         strcpy(m_pcChar,a_pcChar);
    }

    CA::~CA()
    {
         if(m_pcChar != NULL)
         {
              delete []m_pcChar;
              m_pcChar = NULL;
         }
    }

    然后再定义一个函数:
   void test(CA a_clsA)
    {
         int i = 0;
    }

   
    当执行如下代码:
    CA clsTmpA("HelloWorld");
    test(clsTmpA);

    原意是:clsTmpA. m_pcChar 所指的字符串仍然是“HelloWorld”,然而事与愿违的是    clsTmpA. m_pcChar 所值的字符串的值竟然被清掉了。
   
    为什么会这样呢?
    思来想去,终于弄明白了。
    在执行函数test(clsTmpA)的时候,编译器创建一个clsTmpA的副本,当然,这个副本的m_pcChar所指的地址当然与clsTmpA.m_pcChar的地址相同,此时它们所指向的字符串也是相同的。
    但是,当test函数执行完毕退出这个函数时,这个副本也随之消失,因而会执行类CA的修够函数,所以这个副本的m_pcChar指向地址被释放。由于,副本的m_pcChar和clsTmpA.m_pcChar指向的地址相同,在退出函数时,clsTmpA.m_pcChar所指向的字符串被清空也是理所当然的了。

    那么,问题怎么解决呢!
    把函数 void test(CA a_clsA)改成 void test(CA &a_clsA)就解决了。对于修改后的情况,因为参数就是个函数本身(不是副本),所以在test执行完毕,也不会调用其析构函数。

    用VC试试,果真如此,OK!



阅读全文
0 0

相关文章推荐

img
取 消
img