2009-02-23 20 views
9

tengo una clase de C++ y estoy tratando de ejecutarlo en Ubuntu:Crear nueva excepción en C++

#ifndef WRONGPARAMETEREXCEPTION_H_ 
#define WRONGPARAMETEREXCEPTION_H_ 

#include <iostream> 
#include <exception> 
#include <string> 

using namespace std; 

#pragma once 

class WrongParameterException: public exception 
{ 
    public: 
     WrongParameterException(char* message): exception(message) {}; 
     virtual ~WrongParameterException() throw() {}; 
}; 

#endif 

cuando intento compilar, el compilador me da este error:

WrongParameterException.h: In constructor ‘WrongParameterException::WrongParameterException(char*)’: 
WrongParameterException.h:14: error: no matching function for call to ‘std::exception::exception(char*&)’ 
/usr/include/c++/4.3/exception:59: note: candidates are: std::exception::exception() 
/usr/include/c++/4.3/exception:57: note: std::exception::exception(const std::exception&) 

¿Alguien puede decirme qué estoy haciendo mal? Traté de cambiar la variable del mensaje a string o const string o const string&, pero no sirvió de nada.

Aquí es cómo utilizar la nueva excepción de que he creado a partir principal:

std :: excepción no tiene un constructor que toma cualquier tipo de cadena, es sólo un método
try 
{ 
    if ((strToInt1 == -1) || (parameters[1] == NULL) || (strToInt3 == -1) || (parameters[3] != NULL)) 
    { 
      throw WrongParameterException("Error in the config or commands file"); 
    } 
} 
catch(WrongParameterException e) 
{ 
    log.addMsg(e.what()); 
} 
+3

No relacionado con la pregunta, pero importante: no 'use namespace std;' en un encabezado. Segundo, aprenda sobre las clases de excepción estándar que proporciona C++ (std :: runtime_error, logic_error, y domain_error etc.). Catch by const &. Y no incluya para un encabezado de excepción. – gimpf

Respuesta

17

En primer lugar, #pragma once es la forma incorrecta de hacerlo, aprenda acerca de las protecciones incluidas en el encabezado. Related question on SO explica por qué usar #pragma once es la forma incorrecta de hacerlo. Wikipedia explica cómo usar include guards que sirven para el mismo propósito sin ninguno de los inconvenientes.

En segundo lugar, llama al constructor de std :: exception con un parámetro que desconoce, en este caso un puntero a una matriz de caracteres.

#include <stdexcept> 
#include <string> 

class WrongParameterException : public std::runtime_error { 
public: 
    WrongParameterException(const std::string& message) 
     : std::runtime_error(message) { }; 
}; 

Probablemente sea lo que quieras. Para obtener más información sobre excepciones, consulte C++ FAQ Lite article on Exceptions y exceptions article en cplusplus.com.

¡Buena suerte!

+0

Las protecciones de encabezado son más correctas y portátiles, pero si sabe que el código se compilará con los compiladores de MS, #pragma una vez obtendrá una compilación más rápida (no tiene que volver a analizar el archivo para encontrar el #endif coincidente)) –

+0

Especificó que está ejecutando esto en Ubuntu, así que supongo que es GCC. En cuyo caso, la declaración PRAGMA no funciona en primer lugar. –

+7

Estoy bastante seguro de que #pragma una vez es compatible con la versión de gcc que estaba actualizada cuando se escribió este comentario. Si no, es compatible ahora - http://gcc.gnu.org/onlinedocs/gcc-4.6.2/cpp/Alternatives-to-Wrapper-_0023ifndef.html – Steve

9

virtual de lo que() que devuelve la descripción de la excepción.

Tendrá que guardar la cadena usted mismo y devolverla desde allí.

5

std :: el constructor de excepción no toma un argumento de cadena. Está intentando darle uno, que es lo que causa el error de compilación.

Necesita almacenar su cadena, que sería mejor manejar como std :: cadena en lugar de un puntero sin formato, y devolverla desde el método what().

2

En cuanto a la declaración de la clase de excepción en la EM VS2K5, el constructor desea es:

exception (const char *const&); 

así que intenta cambiar su constructor para:

WrongParameterException (const char *const message) 

y ver si eso ayuda. De lo contrario, guarde el puntero en su propia clase e implemente todos los métodos relevantes.

1

Una solución simple es diseñar su excepción de manera diferente. Aquí hay un ejemplo simple:

class MyException : public Exception 
{ 
public: 
    MyException(CString strError) { m_strError = strError; } 

    CString m_strError; 
}; 

Luego puede simplemente usar su mensaje de excepción como lo desee. Esto se debe a que Exception no tiene un contructor que exceptúe un String, por lo que debe restringirlo por su cuenta.

8

Mi consejo sería:

  1. Heredar del std::runtime_error. Según lo recomendado por X-Istence arriba. Conceptualmente es un error de tiempo de ejecución, y también el constructor std::runtime_error acepta un std::string como argumento que describe lo que sucedió.
  2. Acerca de la captura de la excepción. Yo usaría catch(WrongParameterException const& e) (observe la referencia constante) en lugar de catch(WrongParameterException e), porque primero, la excepción es normalmente constante en su caso, y, también, usando la referencia, puede detectar cualquier subclase de WrongParameterException en caso de que su código evolucione con algunos más refinados manejo de excepciones.
Cuestiones relacionadas