用于提升make_shared的用例

时间:2017-10-18 07:10:04

标签: c++

我正在浏览cpp代码并提出以下问题(几乎没有暴露于升级库)

bool xxxx::calcYYY ()
    {
        bool retStatus = false;
        boost::shared_ptr<DblMatrix> price  = boost::make_shared<DblMatrix>(xxx, xxx); 

.....
            retStatus = true;
        }
        return retStatus;
    }

为什么本地作用域指针被实例化为共享?
在高性能代码中,必须有额外的开销来维护引用计数 在这里正确执行此操作的提升替代方案是什么?

2 个答案:

答案 0 :(得分:0)

  

为什么将本地作用域指针实例化为共享?

因为它们指向可以共享的对象。例如,它们可以传递给可以延长它们引用的对象的生命周期的函数。

  

在高性能代码中,必须有额外的开销来维护引用计数。

可能。编译器也可以优化它。有很多技巧,例如通过const引用传递指针以避免必须更改引用计数,尽可能使用std::move,等等,这可能会使额外的开销在许多用例中忽略不计。但是,据推测,它被使用是因为它有一些好处。我们不能仅仅告诉你所展示的代码。

  

在这里正确执行此操作的提升选择是什么?

没有显示任何错误。

答案 1 :(得分:0)

  

为什么将本地作用域指针实例化为共享?

因为作者想要使用一个智能指针,即使函数通过提前返回或异常退出,也可以保证释放内存。

这种用法的最佳选项是public List<JobListItemEntity> getJobs(String query, int startPosition, int count) { Observable<JobList> jobListObservable = mApiService.getOpenJobList( mRequestJobList.setPageNo(startPosition / count + 1) .setMaxResults(count) .setSearchKeyword(query)); List<JobListItemEntity> jobs = mJobDao.getJobsLimitOffset(count, startPosition); //no data in db, make a synchronous call to network to get the data if (jobs.size() == 0) { JobList jobList = jobListObservable.blockingSingle(); updateJobList(jobList, startPosition, false); } else if (shouldRefetchJobList(jobs)) { //data available in db, so show a cached version and make async network call to update data jobListObservable.subscribe(new Observer<JobList>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(JobList jobList) { updateJobList(jobList, startPosition, true); } @Override public void onError(Throwable e) { Timber.e(e); } @Override public void onComplete() { } }); } return mJobDao.getJobsLimitOffset(count, startPosition); } ,但是在C ++ 11之前就没有了,如果原始代码早于它就不会是选项。

下一个最佳选择是public class JobListDataSource<T> extends TiledDataSource<T> { private final JobsRepository mJobsRepository; String query = ""; public JobListDataSource(JobsRepository jobsRepository) { mJobsRepository = jobsRepository; mJobsRepository.setJobListDataSource(this); } @Override public int countItems() { return DataSource.COUNT_UNDEFINED; } @Override public List<T> loadRange(int startPosition, int count) { return (List<T>) mJobsRepository.getJobs(query, startPosition, count); } public void setQuery(String query) { this.query = query; } } 。这实际上完美地处理了这种情况,但它通常没有std::unique_ptr那么有用,因为它不支持移动语义。因此,具有一般规则“只使用boost::unique_ptr并且不再担心”是完全合理的(特别是如果您要将指针传递给可能需要重新分配的通用函数)。

还有std::unique_ptr也可以完美地处理这种情况,但它会让任何阅读代码的人都“坚持下去,这是好的”。最好避免。

  

在高性能代码中,必须有额外的开销来维护引用计数。

如果指针被分配一次,然后在释放之前从未使用过,那么在调用boost::shared_ptr和{{1}的噪声中,原子增量和原子减量的成本将会丢失}}