2009-03-17 9 views
5

Tengo una clase que crea un objeto dentro de un método público. El objeto es privado y no visible para los usuarios de la clase. Este método llama a continuación, otros métodos privado dentro de la misma clase y pasar el objeto creado como un parámetro:Pasar un puntero inteligente como argumento dentro de una clase: scoped_ptr o shared_ptr?

class Foo { 
    ... 
}; 

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

     void privateMethod1(FooPtr fooObj); 

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

Creo que el puntero inteligente correcto en este caso sería un scoped_ptr, sin embargo, no puedo hacer esto porque hace que el scoped_ptr no copiable clase si se usa de esa manera, por lo que debería hacer que los métodos como éste:

void privateMethod1(FooPtr& fooObj); 

privateMethod1 no almacena el objeto, ni mantiene las referencias de la misma. Simplemente recupera datos de la clase Foo.

La forma correcta sería probablemente no usar un puntero inteligente y asignar el objeto en la pila, pero eso no es posible porque utiliza una biblioteca que no permite objetos en la pila, deben estar en el montón .

Después de todo, todavía estoy confundido sobre el uso real de scoped_ptr.

+1

Tengo curiosidad acerca de la biblioteca que 'no permite objetos en la pila'. ¿Hay objetos asignados dentro de la biblioteca en el montón con una fábrica? ¿La biblioteca toma posesión del puntero y lo elimina?¿Cuáles son las razones por las que no puede usar objetos asignados apilados? –

Respuesta

1

Use aquí simple std :: auto_ptr ya que no puede crear objetos en la pila. Y es mejor para su función privada simplemente aceptar puntero sin formato.

El uso real es que no tiene que atrapar todas las excepciones posibles y realizar una eliminación manual.

De hecho, si su objetivo es no modifica el objeto y el objeto de retorno de la API para asegurarse de que será mejor utilizar

void privateMethod1(const Foo& fooObj); 

y pasar el objeto allí como

privateMethod1(*fooObj.get()); 
+0

Ese final es exactamente el mismo que con scoped_ptr, solo que no te obliga a declarar tus parámetros de método como referencias. Pero si no lo hace, se romperá de manera sorprendente (fooObj será un puntero nulo una vez que privateMethod1 regrese, incluso si hay más cosas que le gustaría hacer con él). – sth

+0

estuvo de acuerdo con algo si por supuesto. ¿Por qué usar auto_ptr si scoped_ptr es claramente la mejor opción? transferencia de propiedad no fue intencionada. –

+0

Chicos, no tengo impulso en mi proyecto. Entonces, es por eso que propuse esa solución STL. ¿Dónde ves 'transferencia de propiedad'? –

1

I' Sospecho del comentario "usa una biblioteca que no permite objetos en la pila, deben estar en el Heap".

¿Por qué? Eso generalmente significa que deben ser desasignados de alguna manera especial, por lo que tal vez ninguna de estas soluciones funcione.

+0

@Earwicker el compilador que estamos utilizando es Borland C++ y la biblioteca que estamos utilizando es la biblioteca VCL GUI que se incluye con C++. Eso cambiará pronto, pero tengo que seguir con esto por ahora. Por alguna razón, VCL debe asignarse en el Heap, no tengo una idea real de por qué. –

+0

Probablemente significa que la biblioteca tiene métodos de fábrica que devuelve punteros a objetos creados y le transfiere la propiedad al usuario. –

+0

¿Estás seguro de que necesitas eliminar los objetos? Nunca he usado VCL, pero tengo la vaga idea de que elimina componentes automáticamente cuando se eliminan sus padres. –

3

Una posibilidad adicional es crear el objeto como un static_ptr para facilitar la gestión de memoria, pero sólo tiene que pasar el puntero del crudo a los otros métodos privados:

void privateMethod1(Foo *fooObj); 

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

me gustaría utilizar scoped_ptr dentro showSomethingOnTheScreen, pero pasar una puntero sin formato (o referencia) a privateMethod1, por ejemplo

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

+0

Esa fue mi verdadera conjetura, pero ¿se recomienda esta práctica? Si es eso es lo que haré –

0

En ese caso, solo tiene que reemplazar el mecanismo de asignación.
Crea el objeto en el montón, pero pasa el objeto como referencia a métodos privados.

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

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