views:

868

answers:

5

I have a class that creates an object inside one public method. The object is private and not visible to the users of the class. This method then calls other private methods inside the same class and pass the created object as a parameter:

class Foo {
   ...
};

class A {
   private:
      typedef scoped_ptr<Foo> FooPtr;

      void privateMethod1(FooPtr fooObj);

   public:
      void showSomethingOnTheScreen() {
          FooPtr fooObj(new Foo);
          privateMethod1(fooObj);
      };
};

I believe the correct smart pointer in this case would be a scoped_ptr, however, I can't do this because scoped_ptr makes the class non copyable if used that way, so should I make the methods like this:

void privateMethod1(FooPtr& fooObj);

privateMethod1 doesn't store the object, neither keeps references of it. Just retrieves data from the class Foo.

The correct way would probably be not using a smart pointer at all and allocating the object in the stack, but that's not possible because it uses a library that doesn't allow objects on the stack, they must be on the Heap.

After all, I'm still confused about the real usage of scoped_ptr.

+1  A: 

Use here simple std::auto_ptr as you can't create objects on the stack. And it is better to your private function just simply accept raw pointer.

Real usage is that you don't have to catch all possible exceptions and do manual delete.

In fact if your object is doesn't modify object and your API return object for sure you'd better to use

void privateMethod1(const Foo& fooObj);

and pass the object there as

privateMethod1(*fooObj.get());
Mykola Golubyev
That end's up exactly the same as with the scoped_ptr, just that it doesn't force you to declare your method parameters as references. But if you don't, it'll break in surprising ways (fooObj will be a Null pointer once privateMethod1 returns, even if there is more stuff you'd like to do with it).
sth
agreed with sth if course. why use auto_ptr if scoped_ptr is clearly the better choice? transfer of ownership wasn't intended.
Johannes Schaub - litb
Guys, I don't have boost on the my project. So that's why I proposed such stl solution. Where do you see 'transfer of ownership'?
Mykola Golubyev
nowhere :) but in contrast to scoped_ptr (which explicitly forbids transfer of ownership) there is :) indeed it's fine to use it when you don't have scoped_ptr available i think. i didn't want to say it isn't (and i think neither sth:)) but i think we just wanted to just tell edison about it :)
Johannes Schaub - litb
now what i mean is if he already uses scoped_ptr why does he decide to use auto_ptr now? that's why i commented on it.
Johannes Schaub - litb
Because scoped_ptr does more then he needs: to delete the object when it is out of scope. To avoid different doubts: is this object is going to be passed as scoped_ptr?
Mykola Golubyev
@Mykola it's not needed. If fooObj.get() is a good way to pass the pointer around inside my class that's ok. And I think it is good because I avoid the small overhead of shared_ptr while still relying on a smart pointer. I used the scoped_ptr, but auto_ptr would do the job too.
Edison Gustavo Muenz
+1  A: 

I'm suspicious about the comment "it uses a library that doesn't allow objects on the stack, they must be on the Heap."

Why? That typically means that they must be deallocated in some special way - so perhaps none of these solutions will work.

Daniel Earwicker
@Earwicker the compiler we're using is Borland C++ and the library we're using is the VCL GUI library that is bundled with C++.That will change soon, but I have to stick with this for now.For some reason, VCL must be allocated on the Heap, I have no real idea why.
Edison Gustavo Muenz
Probably it means that library has factory methods that returns pointers to created objects and pass ownership to the user.
Mykola Golubyev
Are you sure you need to delete the objects? I've never used VCL but I've got a vague notion that it deletes components automatically when their parents are deleted.
Daniel Earwicker
+3  A: 

One further possibility is to create the object as a static_ptr for ease of memory management, but just pass the raw pointer to the other private methods:

void privateMethod1(Foo *fooObj);

void showSomethingOnTheScreen() {
  scoped_ptr<Foo> fooObj(new Foo);
  privateMethod1(fooObj.get());
};
sth
+3  A: 

I would use scoped_ptr inside showSomethingOnTheScreen, but pass a raw pointer (or reference) to privateMethod1, e.g.

scoped_ptr<Foo> fooObj(new Foo);
privateMethod1(fooObj.get());

cmeerw
That was my real guess, but is this practice recommended? If it is that's what I'll do
Edison Gustavo Muenz
A: 

In that case, you only have to replace the allocation mechanism.
Create the object on the heap, but pass the object as reference to private methods.

class A {
   private:
      void privateMethod1(Foo& fooObj);

   public:
      void showSomethingOnTheScreen() {
          scoped_ptr<Foo> fooObj(new Foo);
          privateMethod1(*(fooObj.get()));
      };
};
total