3

What is good practice to implement a set function for a class variable which is stored in a pointer (due to the need of polymorphism).

Do I pass a pointer to the set function or the object by reference? Also what is the textbook way of making sure no memory leaks exist? (Unfortunately, I can't use smart pointers.)

The way I see it I have two options:

class A {
  B* b;
  setB(B& newB) {
     delete b;
     b = &newB;
  }

  //vs:

  setB(B* newB) {
     delete b;
     b = newB;
  }
};
user695652
  • 4,105
  • 7
  • 40
  • 58
  • You cannot call delete, unless you certainly know the passed value was actually created with new. I'd recommend using a smart pointer instead (e.g. `std::unique_ptr`). – πάντα ῥεῖ Aug 11 '15 at 21:13
  • What exactly do you mean with correctly implement? Are you refering to good practices or how to use the C++ language? – univise Aug 11 '15 at 21:14
  • I'm referring to good practice – – user695652 Aug 11 '15 at 21:15
  • @user695652 As mentioned _good practice_ would be not to use raw pointers at all. – πάντα ῥεῖ Aug 11 '15 at 21:17
  • If you know your pointer should never be a null pointer use a reference; references cannot be NULL so the client does not get a chance to pass an invalid pointer. Also make sure that 'b' is a valid pointer to valid data; you cannot delete null pointers, data that was already deleted, or has never been initialised. – univise Aug 11 '15 at 21:17
  • I do not think you need smart pointer here because it should be easy to maintain a good internal state. – univise Aug 11 '15 at 21:24
  • In theory it is also easy to make pigs fly. Go with the smart pointer. The overhead is minimal and the safety benefits huge. – user4581301 Aug 11 '15 at 21:36
  • The textbook way of doing it is smart pointers. There are no textbook ways, or indeed any ways, of doing it correctly otherwise. – Puppy Aug 11 '15 at 21:51

1 Answers1

1

Since C++11, I believe the correct way is to use an std::unique_ptr<B>:

#include <memory>

class A {
  std::unique_ptr<B> b;
  void setB(std::unique_ptr<B>&& newB) {
     b = std::move(newB);
  }
};

and to call it, do:

std::unique_ptr<B> b(new B(/* ... */));
obj_A.setB(std::move(b));

A parameter of the type std::unique_ptr<B>&& will ensure to the user of your function that you are taking the ownership of the pointer to yourself.

EDIT:

As univise pointed, OP doesn't want to use smart pointers. I can't infer from the question why is it so, but if it is about resource usage, know that using a std::unique_ptr like this has zero overhead, either in compiled code size or in pointer object size.

lvella
  • 12,754
  • 11
  • 54
  • 106
  • Although your answer ok, you should note that the OP said she/he cannot use/would like to avoid use of smart pointers because it is being used in an embedded system. – univise Aug 11 '15 at 21:26
  • @univise Why do you say OP is coding for an embedded system? – lvella Aug 11 '15 at 21:40
  • @Ivella The comments said so, they have just be edited by the OP. The unedited version stated that we are dealing with an embedded system. Your answer is good. EDIT: Now, in the question it states: "Unfortunately, I can't use smart pointers." at the end of the second paragraph. – univise Aug 11 '15 at 21:43
  • Wondered that myself. In embedded systems safety should trump virtually all other considerations. – user4581301 Aug 11 '15 at 21:46