C++ 局部变量使用规则

C++ 局部变量使用规则

目录

1.说明

局部变量为函数中常用的一直数据方式,它的初始化可以自己调用也可以由函数返回来完成. 本着以尽可能少的调用复制构造或者赋值函数的前提下,应该尽可能的采样由函数返回初始化来完成.(类型可以用auto 推断,完美偷懒) 对于生命周期来说,应该尽可能的靠近使用的地方,而不是在函数进入时统一声明.(申明调用构造函数需要浪费时间) 如果某个类的实例的生命周期在本函数内,且占用大量空间,可以在使用完之后提前释放.

2.例程

1.类的实例,空间结束时内存可以再利用.(std::move)

a.修改前

void  CLocalSectionMap::seedFloodFill(const CChainCell &seed, const int raw_value, const int new_value, CChain &seek_deque)
{
    seek_deque.clearList();
    if(isOutOfBounds(seed.getIdx(), seed.getIdy()))
    {
        return;
    }
    std::deque<CChainCell> last_seeks ;
    last_seeks.push_back(seed);  
    std::deque<CChainCell> new_seeks;
     ...
    while(!last_seeks.empty())
    {
        new_seeks.clear();
        for(size_t i = 0; i < last_seeks.size(); i++)
        {
            generateNewSeeks(last_seeks.at(i), raw_value, new_value, new_seeks);
        }
        for(size_t i = 0; i < new_seeks.size(); i++)
        {
            seek_deque.addUniqueElement(new_seeks.at(i));
        }
        last_seeks.clear();  
        last_seeks = new_seeks;
    }
}

b.修改后:

void CLocalSectionMap::seedFloodFill( const algo::CChainCell& seed, int raw_value, int new_value,
                                      algo::CChain& seek_deque)
{
    ...
    std::deque< algo::CChainCell > last_seeks;
    last_seeks.push_back( seed);
    ...
    while ( !last_seeks.empty())
    {
        std::deque< algo::CChainCell > new_seeks; //声明周期局部化

        for(auto &v : last_seeks)
        {
            generateNewSeeks(v, raw_value, new_value, new_seeks);
        }

        for(auto &v : new_seeks)
        {
            seek_deque.addUniqueElement(v);
        }

        last_seeks = std::move(new_seeks); //右值拷贝效率高(相当于指针交换)
        //注意右值后不要再访问new_seeks,否则后果不可预测.
    }
}

2.类的生命周期已经结束,可以提前释放

a.修改前

bool CPathPlanAstar::processPathPlan( ...)
{
    ...
    COccupiedGridMapProcess grid_map_process;

    /* Initialize the map */
    initialMap(grid_map);

    if(m_coverage_plan_flag)
    {
        grid_map_process.setPunishmentLength(0.05);
        grid_map_process.setObstacleThreshold(m_params.obstacle_threshold);
    }
    else
    {
        grid_map_process.setPunishmentLength(m_params.punishment_length);
        grid_map_process.setObstacleThreshold(m_params.obstacle_threshold);
    }

    grid_map_process.gridMapInflation(grid_map, m_map_punishment, m_map); //占用大量内存
    fillBlank(grid_map, target_pose, m_params.punishment_length);
    ....
}

b.修改后:

bool CPathPlanAstar::processPathPlan( ...)
{
   ...
   {
       COccupiedGridMapProcess grid_map_process;

       initialMap(grid_map);

       if(m_coverage_plan_flag)
       {
         grid_map_process.setPunishmentLength(0.05);
         grid_map_process.setObstacleThreshold(m_params.obstacle_threshold);
       }
       else
       {
         grid_map_process.setPunishmentLength(m_params.punishment_length);
         grid_map_process.setObstacleThreshold(m_params.obstacle_threshold);
       }
       grid_map_process.gridMapInflation(grid_map, m_map_punishment, m_map);
   } //生命周期结束. 提前释放空间

   fillBlank(grid_map, target_pose, m_params.punishment_length);
   ....
}