El enfoque común aquí es arrojar una excepción (y manejarla en algún lugar más arriba).
Uno de los beneficios del mecanismo de excepción es que le permite lanzar una excepción desde dentro de un constructor de clase. En ese caso, nunca se llega a la situación en la que se devuelve un puntero al inválido. Usted "obtendrá el control" en el bloque catch correspondiente. Si el puntero solo fue declarado dentro del bloque try (o en algún otro método invocado por el bloque try), estaría fuera de su alcance en ese bloque catch.
Eso no es un truco, es bastante legítimo y una técnica de programación común. Por ejemplo, si el constructor de su clase asigna memoria dinámicamente (por ejemplo, para un búfer interno) y esta asignación falló, le conviene lanzar una excepción porque al final del cuerpo del constructor no tendría un objeto válido.
Aquí es un ejemplo (que he estado haciendo de Java durante los últimos 10 años, por lo que mi código C++ a continuación está probablemente en mal estado aquí, tal vez alguien puede editar esto para mí)
// Begin C++ code written by a Java programmer... :)
class Myclass
{
public:
Myclass(int length)
{
if(length<=0) throw BadBufferSizeException("Bla bla bla");
this->buffer = (char*)malloc(length*sizeof(char)); // don't remember the new syntax
}
void doSomething()
{
// Code for placing stuff in the buffer
}
private:
char* buffer;
};
int main()
{
try
{
int len;
len = getLengthFromUser();
MyClass* pMyClass = new MyClass(len);
myClass->doSomething();
} catch(const Exception & e)
{
// Whatever... Note how pMyClass is not even accessible here
}
}
Tenga en cuenta que si usted definió pMyclass como nulo fuera del bloque try, y luego solo lo reasignó dentro del bloque try cuando crea la clase; en el caso de falla, es probable que aún tenga nulo, pero nunca habría ejecutado doSomething(). Si le preocupa la inicialización, también puede mover la llamada a DoSomething() fuera del bloque try-catch, pero querrá asegurarse de que su puntero no sea nulo.
También tenga en cuenta que C++ le da más (¿demasiado?) Libertad a la hora de tirar cosas que otros idiomas. Normalmente me gusta tener una jerarquía de clases de excepción o utilizar una biblioteca existente con dicha jerarquía.
Esto es también lo que las preguntas frecuentes de C++ recomiendan http://www.parashift.com/c++faq-lite/exceptions.html#faq-17.2 –
Gracias, Uri. Entonces, ¿debería hacer algo como 'try {if (!Esto()) tira 20; } 'en el constructor y omite la instrucción' catch', ¿o es necesaria la instrucción 'catch'? –
@Jim: Permítanme editar mi respuesta con un ejemplo – Uri