不必要的对象副本 - C ++ STL

时间:2014-02-26 23:28:24

标签: c++ stl

伙计们,我正在使用标准模板语言,几个月前我开始阅读更多关于它的内容,并实施一些练习。我在这里有这个代码:

class Student {
// many attributes and methods here plus:
char* name; // Student name
char* courseName; // Student course name
std::string toString() { return std::string(name); }
}

std::string FindCourseName ( std::list< Student > stu, string name )
{
    for ( std::list< Student >::iterator it = stu.begin();
    it != stu.end();
    it++ )
    {
            if ( (*it).toString() == name )
            {
                return it->courseName;
            }
    }
return "";
}

练习要求:

a)在FindCourseName方法中完成了多少不必要的对象创建/复制? b)你如何减少这份数量? c)您如何优化上面的代码?

我多次阅读这段代码而且看不到任何不必要的对象副本,你们可以点亮我的脑袋吗?哈哈哈非常感谢!

2 个答案:

答案 0 :(得分:0)

我会根据赋值请求按以下方式重写函数,前提是类本身可能不会被更改,并且除了在函数类方法中使用之外,其所有数据成员都是私有的

std::string FindCourseName ( const std::list< Student > &stu, const string &name )
{
    for ( std::list< Student >::const_iterator it = stu.cbegin(), last = stu.cend();
    it != last;
    ++it )
    {
            if ( (*it).toString() == name )
            {
                return it->courseName;
            }
    }
return "";
}

如果数据成员名称是公开的,那么我会写

            if ( (*it).name == name )
            {
                return it->courseName;
            }

虽然由于优化和复制/移动构造函数省略,但没有太大区别。

答案 1 :(得分:0)

  1. 由于两个函数参数按值捕获,因此stuname都是副本传入的内容。这很糟糕。
  2. (*it).toString()制作it->name作为string的副本,但这是值得商榷的,因为string非常方便,而且很难搞砸,所以这种事物很常见。
  3. it++会返回增量之前的副本,但是大多数人都不会计算它,因为它经过了如此简单的优化。
  4. 在C ++ 03中,return std::string(name); 有时可以创建名称的附加临时字符串副本。这主要是理论上的,所以很少有人相信这一点。
  5. 由于FindCourseName返回string,它会将返回值的副本复制为string,但同样,这是有争议的,因为string是好的。