2009-02-23 10 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.
Problemi correlati