C ++对shared_ptr vs引用的引用

时间:2009-10-09 09:23:49

标签: c++ boost class-design shared-ptr

所有

我最近在DAL设计上发布了此question。从中可以看出,将对象的引用传递给函数,然后使用该函数填充该对象,这将是C ++数据访问层的良好接口,例如。

  bool DAL::loadCar(int id, Car& car) {} 

我现在想知道是否使用对boost :: shared_ptr的引用会更好,例如。

  bool DAL::loadCar(int id, boost::shared_ptr<Car> &car)

有什么想法?有人提供优势吗?

将const正确性应用于两个调用会产生什么影响?

提前致谢。

4 个答案:

答案 0 :(得分:3)

这取决于功能的作用。

通常,带有指针的函数表示调用者可能会调用此函数,即使它们没有要传递给它的对象 - 它们总是可以传递NULL。如果符合函数规范,则使用(智能)指针。通过引用传递引用计数智能指针而不是复制它们是一种优化(而不是过早的,我应该添加),因为它避免了不必要地增加和减少引用计数,这在MT环境中可能是明显的性能损失。

将非const引用作为参数的函数期望传递一个可能更改的有效对象。调用者不能(合法地)调用该函数,除非他们有一个有效的对象,除非他们愿意让函数改变对象的状态,否则他们不会调用它。如果更符合函数规范,请使用引用。

答案 1 :(得分:3)

正如 sbi 所说,“这取决于功能的作用。”

但是,我认为上述最重要的方面不是是否允许NULL,而是该函数是否存储指向该对象的指针供以后使用。如果函数只填充了一些数据,那么我会使用引用,原因如下:

  • 该函数仍然可以由不使用shared_ptr,用于堆栈对象等的客户端使用。
  • 使用shared_ptr的函数仍然是微不足道的 - shared_ptr具有返回引用的解引用运算符
  • 无法传递NULL
  • 少输入
  • 我不喜欢使用“东西”,而我不需要

如果函数需要存储指针供以后使用,或者您预期函数可能会以需要存储指针的方式更改,则使用shared_ptr。

答案 2 :(得分:1)

如果必须接收有效对象(即您不希望调用者传递NULL),那么请不要使用boost :: shared_ptr。你的第二个例子传递了对“智能指针”的引用....忽略细节,它是“指向Car的指针”。因为它是引用,所以shared_ptr对象不能为NULL ....但这并不意味着它不能具有NULL值(即指向“null”对象)。

我不明白为什么你会认为对智能指针的引用会“更好” - 调用者函数是否已经使用智能指针?

至于“const”的含义......你的意思是

bool DAL::loadCar(int id, const Car& car) {}

? 如果是,那将会适得其反,你向编译器传达“汽车”不会改变的事实(但可能是你希望它改变!)。

或者你的意思是使函数“const”,如

class DAL{
   bool loadCar(int id, Car& car) const;
}

在后一种情况下,您向编译器/ API用户通知方法“loadCar”不会修改DAL对象。如果这是真的,那么这是一个好主意 - 不仅它能够实现一些编译器优化,而且在“契约”(函数签名)中指定该函数不对DAL进行任何修改通常是一件好事,特别是如果你在你的代码中做了这个隐含的假设(这样你就可以确保它保持正确,并且将来没有人会以改变“DAL”对象的方式修改“loadCar”函数)

答案 3 :(得分:0)

在第一种情况下,您只需传递汽车并“填写”信息。例如,您可以创建一个“默认”汽车,然后填写它。我看到一个不便之处:拥有两类汽车并不是一件好事:一辆是穷人,默认的,无用的,“空车”,还有一辆真正装满汽车的汽车。对我来说,汽车是一辆汽车,所以它应该是一辆有效的汽车(例如我可以从A位置开车到B级;我可以在你的功能之前和之后加速,制动,启动,停止)。

我通常使用传统指针,而不是提升(顺便说一句,没有问题)所以我真的无法评论后一种选择。