0

I want to return an implementation of a class from a function. The function is in a library. I want to prevent the user from destroying the objects I return. How can I achieve this?

EDIT: Example.

Interface to the world:

class Base
{
   public:
      virtual void foo() = 0;
};

Base* GetFoo();

Implementation - Internal:

class Bar : public Base
{
    public:
        void foo() { //Do something}
};

Base* GetFoo()
{
   return new Bar
}
nakiya
  • 14,063
  • 21
  • 79
  • 118
  • A bit out of scope of the original question, but I am not sure why are you using a separate function to get interface base (instance of bar). And why are you not using factory method. –  Dec 06 '10 at 06:21
  • 1
    Just program the computer to blow up the monitor if the user tries it. – Edward Strange Dec 06 '10 at 06:34
  • I believe you wanted the constructor to Bar() be private as well? – Jaywalker Dec 06 '10 at 06:46
  • Don't return a pointer (a pointer implies that he has the option of deleting (though not really)). If you return a reference then the user has no excuse to delete it. – Martin York Dec 06 '10 at 08:37

6 Answers6

8

You could use a private destructor and create some method (release()) to allow the object to be freed in a controlled manner.

Community
  • 1
  • 1
nc3b
  • 15,562
  • 5
  • 51
  • 63
2

And to answer your question as you are deriving from base, so you cannot make base destructor private. You can achieve your goal by protected destructor.

1

Return a shared_ptr<Base> and keep a copy of the pointer yourself. That pointer will keep the object alive, no matter what the user will do with his shared_ptr<Base>. You might even consider returning a weak_ptr<Base> instead, to stress that the lifetime of the object is subject to your whims only.

MSalters
  • 173,980
  • 10
  • 155
  • 350
0

Why would you want to do that? The user should be getting a copy of the returned object anyway, and it should be up to them whether to allocate or deallocate the copy.

neckbeard
  • 123
  • 1
  • 2
    -1: A particularly unhelpful answer - in complex systems the question poses a realistic and not uncommon requirement. "getting a copy" may be completely useless if they're being given an accessor to some centralised service, and it's quite possible that the service holds open some hardware or OS resources that shouldn't be continually affected by constructors and destructors. Even smart pointers imply some performance and memory usage compromises. It's reasonable to explain the pros cons of an approach, but not good to ignore the question. – Tony Delroy Dec 06 '10 at 06:36
  • -1. Agreed with tony. Especially if you are doing performance sensitive stuff, you don't want the user to mess up the object pool by destroying (Thereby not enabling the pool to reclaim that memory). And even construction should be avoided by user just because it is costly. – nakiya Dec 06 '10 at 06:51
0

You cannot prohibit the user of your library to shoot himself in a leg while cleaning a loaded gun. I.e. even if you return a constant reference, one could take address from it and then delete it. So you should make your code stable even in this situation.

P.S. private destructors (@nc3b) impose limitations on a further usage of the class (no more local non-dynamic instances, for example), so consider them wisely.

Haspemulator
  • 11,050
  • 9
  • 49
  • 76
  • 4
    I don't agree that one should make their code stable in *all* situations, including when the user is obviously trying to break your library, which what you just described sounds like. It can be done when it's feasible, but in many cases trying to account for every kind of idiocy people might come up with is silly. – Matti Virkkunen Dec 06 '10 at 06:24
  • @Matti, I agree, not each and every case should be cared of, but I believe that in each and every situation there's a reasonable compromise between idiocy-protection and self-health-checking, so to say. – Haspemulator Dec 06 '10 at 06:56
0

If what you're returning is a new object, then there is no reason why you should need to prevent the user from delete ing it.

However, you shouldn't leave any question about responsibility for deletion. Instead, either use a smart pointer to return the value, or use the polymorphic pImpl pattern (wherein a non-polymorphic wrapper contains a smart pointer to a polymorphic implementation - typically a smart pointer that provides value semantics, such as this ) instead of just returning a derived instance.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153