ethz-asl / programming_guidelines

This repository contains style-guides, discussions, eclipse/emacs auto-formatter for commonly used programming languages
139 stars 38 forks source link

What is the correct use of shared pointers? #23

Open furgalep opened 9 years ago

furgalep commented 9 years ago

We use shared pointers for memory management but I still have some questions on what is the best use.

Let's say I have a class, Frame, that has a shared_ptr member Camera. The camera is shared among many frames. I have some questions about best practices:

class Frame {
public:
  // Q1
  Frame(std::shared_ptr<Camera> camera) : camera_(camera) {}

  // Q2
  std::shared_ptr<Camera> getCamera() const{ return camera_; }

  // Q3
  void setCamera( std::shared_ptr<Camera> camera ) { camera_ = camera; }
private:
  std::shared_ptr<Camera> camera_;
};

Questions:

Q1. What should the constructor take as an argument: std::shared_ptr<Camera>, or const std::shared_ptr<Camera>&, or something else?

Q2. What should getCamera() return, std::shared_ptr<Camera>, or const std::shared_ptr<Camera>&, or const std::shared_ptr<const Camera>&, or something else? Or should we have a const and a non-cost version. And should we name the non-const version getCameraMutable()?

Q3. What should setCamera() take as an argument: std::shared_ptr<Camera>, or const std::shared_ptr<Camera>&, or something else?

furgalep commented 9 years ago

@simonlynen, @schneith, anyone else?

uschwes commented 9 years ago

Isn't the reference counter screwed up when you pass shared pointer by reference?

PascalGohl commented 9 years ago

I am following this suggestion: "Shortly, there is no reason to pass by value, unless there is multi-threading going on, but this needs to be considered separately." From: http://stackoverflow.com/a/8741626

uschwes commented 9 years ago

Oh, I see. Ok when you assign to member directly.

Shouldn't there be also a method to make the refered object const?

std::shared_ptr<const Camera> getCamera() const;

How would that method look like if the member is a ´´´std::shared_ptr´´´?

HannesSommer commented 9 years ago

About Q2:

HannesSommer commented 9 years ago

Again Q2: To be fast I would return const std::shared_ptr<Camera>& rather than std::shared_ptr<Camera>, and ideally make the getter inline (= don't prevent it by defining it in a cpp file), to have the optimizers optimize the reference to an pointer indirection. Why would one want that extra copy into a temporary object (yielding ownership management overhead)? Move semantics or return value optimization is impossible here, as you return a member, which isn't a temporary object. Of course it that temporary is assigned to a local it will be moved but that is still less efficient than directly copying from a reference. And in some cases it won't be assigned, like e.g. in things like: frame->getCamera()->getStuff(). Of course multi threading can again change a lot here...