我正在浏览cpp代码并提出以下问题(几乎没有暴露于升级库)
bool xxxx::calcYYY ()
{
bool retStatus = false;
boost::shared_ptr<DblMatrix> price = boost::make_shared<DblMatrix>(xxx, xxx);
.....
retStatus = true;
}
return retStatus;
}
为什么本地作用域指针被实例化为共享?
在高性能代码中,必须有额外的开销来维护引用计数
在这里正确执行此操作的提升替代方案是什么?
答案 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}的噪声中,原子增量和原子减量的成本将会丢失}}