2010-09-04 126 views
13

estoy tratando de escribir una función que compruebe si existe un objeto:¿Cómo puedo comprobar si existe un objeto en C++

bool UnloadingBay::isEmpty() { 
    bool isEmpty = true; 
    if(this->unloadingShip != NULL) { 
     isEmpty = false; 
    } 
    return isEmpty; 
} 

soy bastante nuevo en C++ y no está seguro si mi fondo de Java es confuso algo, pero el compilador da un error:

UnloadingBay.cpp:36: error: no match for ‘operator!=’ in ‘((UnloadingBay*)this)->UnloadingBay::unloadingShip != 0’ 

Parece que no puedo entender por qué no funciona.

Aquí está la declaración de la clase UnloadingBay:

class UnloadingBay { 

    private: 
     Ship unloadingShip; 

    public: 
     UnloadingBay(); 
     ~UnloadingBay(); 

     void unloadContainer(Container container); 
     void loadContainer(Container container); 
     void dockShip(Ship ship); 
     void undockShip(Ship ship); 
     bool isEmpty(); 

}; 
+0

¿IsloadingShip es una función de clase? ¿Puedes publicar tu declaración de clase? –

+0

No unloadingShip es un atributo de unLoadingBay, que es la clase donde isEmpty es miembro –

+4

pharma_joe: Como consejo general: ¿Todo lo que aprendió en Java? Olvídalo. No te ayudará en C++. – greyfade

Respuesta

22

Parece que es posible que necesite un manual sobre el concepto de "variable" en C++.

En C++ la duración de cada variable está ligada a su alcance abarcador. El ejemplo más sencillo de esto es las variables locales de una función:

void foo() // foo scope begins 
{ 
    UnloadingShip anUnloadingShip; // constructed with default constructor 

    // do stuff without fear! 
    anUnloadingShip.Unload(); 
} // // foo scope ends, anything associated with it guaranteed to go away 

En el código anterior "anUnloadingShip" está predeterminado construido cuando se introduce la función foo (es decir, se introduce su alcance). No se requiere "nuevo". Cuando el ámbito abarcante se va (en este caso, cuando foo sale), el destructor definido por el usuario se llama automáticamente para limpiar el UnloadingShip. La memoria asociada se limpia automáticamente.

Cuando el alcance que abarca es una clase de C++ (es decir, una variable miembro):

class UnloadingBay 
{ 
    int foo; 
    UnloadingShip unloadingShip; 
}; 

el tiempo de vida está ligada a las instancias de la clase, así que cuando nuestra función crea un "UnloadingBay"

void bar2() 
{ 
    UnloadingBay aBay; /*no new required, default constructor called, 
         which calls UnloadingShip's constructor for 
         it's member unloadingShip*/ 

    // do stuff! 
} /*destructor fires, which in turn trigger's member's destructors*/ 

los miembros de aBay se construyen y viven mientras "aBay" viva.

Todo esto se resuelve en tiempo de compilación. No hay recuento de referencias en tiempo de ejecución que impida la destrucción.No se hacen consideraciones para cualquier otra cosa que pueda refer to o point to esa variable. El compilador analiza las funciones que escribimos para determinar el alcance y, por lo tanto, la duración de las variables. El compilador ve dónde termina el alcance de una variable y todo lo que se necesita para limpiar esa variable se insertará en tiempo de compilación.

"nuevo", "NULO", (no olvide "eliminar") en C++ entren en juego con los punteros. Los punteros son un tipo de variable que contiene una dirección de memoria de algún objeto. Los programadores usan el valor "NULL" para indicar que un puntero no contiene una dirección (es decir, no apunta a nada). Si no está usando punteros, no necesita pensar en NULL.

Hasta que domine cómo entran y salen las variables en C++, evite los punteros. Es otro tema completamente.

¡Buena suerte!

+0

Hola muchas gracias, lo aprecio mucho. Los indicadores me dan un pequeño problema para entender, pero estoy llegando. Cheers –

+0

Me gusta la parte "garantizada" :-) ¡Especialmente si algún tío decide lanzar una excepción en destructor! –

+0

@Vlad, cuando se arroja un destructor, se garantiza que su programa desaparecerá, de cualquier forma, la variable desaparece :) –

1

Asumo unloadingShip es un objeto y no un puntero de modo que el valor nunca puede ser NULL.

es decir.

SomeClass unloadingShip

frente

SomeClass * unloadingShip

+0

Sí, es un objeto. ¿Cómo puedo verificar si la instancia de descarga está instanciada o no? –

+3

Si UnloadingBay se crea una instancia, entonces su objeto de descarga de descarga también se instancia (incluso si está en el constructor de UnloadingBay). – EboMike

+0

si se crea una instancia de "this" (también conocido como el objeto UnloadingBay), también se creará una instancia de descarga de nave, porque unloadingShip es parte del objeto UnloadingBay. es decir, el objeto UnloadingBay y el objeto UnloadingShip son parte del mismo bloque de memoria, si se quiere. No es como Java, donde cada objeto debe asignarse de forma individual. –

1

Bueno, usted no tiene que escribir tanto código para comprobar si un puntero es NULL o no. El método podría ser mucho más simple:

bool UnloadingBay::isEmpty() const { 
    return unloadingShip == NULL; 
} 

Además, se debe marcar como "const", ya que no modifica el estado del objeto y se puede llamar en casos así constantes.

En su caso, "unloadingShip" es un objeto de la clase "UnloadingShip" que no está asignado dinámicamente (excepto cuando toda la clase "UnloadingBay" se asigna dinámicamente). Por lo tanto, comprobar si es igual a NULL no tiene sentido porque no es un puntero.

+0

OK He agregado la declaración. ¡Gracias! –

1

para comprobar, si existe un objeto, se puede considerar ir de esta manera:

crear un puntero a su objeto:

someClass *myObj = NULL // Make it null 

y ahora donde se pasa este puntero, se puede comprobar:

if(!myObj) // if its set null, it wont pass this condition 
    myObj = new someClass(); 

y luego en caso de que quiere eliminar, se puede hacer esto:

if(myobj) 
{ 
    delete myObj; 
    myObj = NULL; 
} 

de esta manera, puede tener un buen control al verificar si su objeto existe, antes de eliminarlo o antes de crear uno nuevo.

Espero que esto ayude!

Cuestiones relacionadas