2009-02-23 8 views
9

ho una classe C++ e sto cercando di farlo funzionare in Ubuntu:Creazione di nuova eccezione in 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 

quando provo a compilarlo, il compilatore mi dà questo errore:

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&) 

Qualcuno può dirmi cosa sto sbagliando? Ho provato a cambiare la variabile del messaggio in string o const string o const string& ma non è stato di aiuto.

Ecco come io uso la nuova eccezione che ho creato dal principale:

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

Non correlato alla domanda, ma importante: non utilizzare 'namespace std;' in un'intestazione. In secondo luogo, scopri le classi di eccezioni standard fornite da C++ (std :: runtime_error, logic_error e domain_error ecc.). Catch di const &. E non includere per un'intestazione di eccezione. – gimpf

risposta

17

Per prima cosa, #pragma once è il modo sbagliato per farlo, scopri le protezioni di intestazione. Related question on SO spiega perché l'utilizzo di #pragma once è la soluzione sbagliata. Wikipedia spiega come usare include guards che servono allo stesso scopo senza nessuno dei lati negativi.

In secondo luogo, si sta chiamando il costruttore di std :: exception con un parametro che non conosce, in questo caso un puntatore a un array di caratteri.

#include <stdexcept> 
#include <string> 

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

Probabilmente sarebbe quello che vuoi. Per ulteriori informazioni sulle eccezioni, consulta C++ FAQ Lite article on Exceptions e exceptions article su cplusplus.com.

Buona fortuna!

+0

I guardie di intestazione sono più corretti e portabili, ma se si conosce che il codice deve essere compilato con i compilatori MS, allora #pragma una volta avrà una compilazione più veloce (non ha il file di analisi per trovare il numero #endif corrispondente). –

+0

Ha specificato che sta eseguendo questo su Ubuntu, quindi presumo che sia GCC. Nel qual caso la dichiarazione PRAGMA non funziona in primo luogo. –

+7

Sono abbastanza sicuro che #pragma una volta sia supportato dalla versione gcc che era corrente quando questo commento è stato scritto. In caso contrario, è supportato ora - http://gcc.gnu.org/onlinedocs/gcc-4.6.2/cpp/Alternatives-to-Wrapper-_0023ifndef.html – Steve

9

std eccezione non ha un costruttore che prende qualsiasi tipo di corda, è solo un metodo :: virtuale che cosa() che restituisce la descrizione dell'eccezione.

Sarà necessario memorizzare la stringa e restituirla da lì.

5

std :: Il costruttore di eccezioni non accetta un argomento stringa. Stai provando a dartene uno, che è ciò che causa l'errore di compilazione.

È necessario archiviare la stringa, che sarebbe meglio gestire come una stringa std :: anziché un puntatore raw e restituirla dal metodo what().

2

Guardando la dichiarazione della classe di eccezione in MS VS2K5, il costruttore che si desidera è:

exception (const char *const&); 

quindi provare a modificare le costruttore per:

WrongParameterException (const char *const message) 

e vedere se questo aiuta. Altrimenti, memorizza il puntatore nella tua classe e implementa tutti i metodi pertinenti.

1

Una soluzione semplice è progettare la vostra eccezione in modo diverso. Ecco un semplice esempio:

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

    CString m_strError; 
}; 

Quindi è possibile utilizzare semplicemente il messaggio di eccezione a piacere. Ciò è dovuto al fatto che Exception non dispone di un contructor che consente di escludere una stringa, pertanto è necessario eseguirla autonomamente.

8

Il mio consiglio è:

  1. Eredita da std::runtime_error. Come consigliato da X-Istence sopra. È concettualmente un errore di runtime e anche il costruttore std::runtime_error accetta un std::string come argomento che descrive cosa è successo.
  2. Informazioni su come rilevare l'eccezione. Vorrei usare catch(WrongParameterException const& e) (notare il riferimento const) invece di catch(WrongParameterException e), perché in primo luogo, l'eccezione è normalmente costante nel tuo caso e, inoltre, usando il riferimento, prendi qualsiasi sottoclasse di WrongParameterException nel caso il tuo codice si evolva con alcuni più raffinati la gestione delle eccezioni.