XML | HTML | TXT
您当前位置:软件开发 >> 新闻动态 >> 软件开发技术 >> 浏览文章

C++陷阱之慎用string类

我们知道,string类为我们提供了很多的便利,我们用string类能方便的做字符串的各种操作,避免了我们直接操作char指针而产生的一些繁琐的操作,和内存泄露的可能性,可是string类也是有陷阱的。下面我们看这样一个例子,你能看出问题所在吗?

 

复制代码

string getString()

{

    return "just a test";

}

void test()

{

    const char *pc = getString().c_str();

    cout<<pc<<endl;

}

复制代码

 

如果看不出来可以实际运行一下,会发现输不出结果来,这是为什么呢?

 

当我们写getString函数时,如果其返回类型是const char*我们可能会分外小心,因为我们知道"just a test"生命会在函数返回后结束,我们可能会new一段空间来放这个字符串,然后返回指针,或者是要求调用者给一个空间来放这个字符串。但是当返回类型是string时,我们就不会如此小心翼翼,因为我们知道string类实现了拷贝构造函数和赋值函数。它会为我们操心空间分配和销毁的问题。所以在这里,我们直接返回"just a test"字符串是没有问题的。

 

接着我们对一个string对象调用c_str函数貌似也没有什么问题,因为这是string类提供给我们的功能。但是这里的关键是,我们没有将getString()的结果赋给一个string对象就直接获取其指针了,这时,系统并不会为string调用拷贝构造函数或是赋值函数,返回的string仍然只是一个临时对象的状态,它会在完成对pc的赋值后被销毁,这时其内部的数据也不会存在了。

 

怎么解决这个问题呢?

 

我们要改变c_str函数,让它不要直接返回指针,而是new一段空间来放这个字符串再返回指针吗?这样,会降低效率,且每个调用c_str函数的用户都需要操心delete指针的问题,很容易造成内存泄露。

 

我们要改写getString函数,重新为返回的字符串new一段空间吗?这么做显然也不合适。

 

这时,我们有两种比较可行的解决方法。

 

1.不要直接返回临时对象的指针,将临时对象先赋值给一个局部对象,再获取其指针。这样,将上例改写为

 

void test()

{

    string str = getString();

    const char *pc = str.c_str();

    cout<<pc<<endl;

}

 

 

2.如果要使用临时对象的指针,将所有的使用放到一个语句里进行。这样,将上例改写为

 

void test()

{

    cout<<getString().c_str()<<endl;

}


手机:18678812288 E-Mail:1069706080@qq.com
地址:山东省济南市舜耕路泉城公园东门园内向北50米 鲁ICP备07011972号 版权所有2008-2013 山东赢德信息科技有限公司