2009-02-23 9 views
9

J'ai une classe C++ et je suis en train de l'exécuter dans Ubuntu:Création d'une nouvelle exception 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 

lorsque je tente de le compiler, le compilateur me donne cette erreur:

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

Quelqu'un peut-il me dire ce que je fais mal? J'ai essayé de changer la variable de message à string ou const string ou const string& mais cela n'a pas aidé.

Voici comment j'utilise la nouvelle exception que j'ai créé à partir 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

Sans rapport avec la question, mais important: n'utilisez pas l'espace de noms std; dans un en-tête. Ensuite, découvrez les classes d'exception standard fournies par C++ (std :: runtime_error, logic_error et domain_error etc.). Attraper par const &. Et n'incluez pas pour un en-tête d'exception. – gimpf

Répondre

17

Tout d'abord, #pragma once est la mauvaise façon de procéder, en savoir plus sur les gardes d'en-tête. Related question on SO explique pourquoi utiliser #pragma once est la mauvaise façon de faire. Wikipedia explique comment utiliser include guards qui servent le même but sans aucun des inconvénients. Deuxièmement, vous appelez le constructeur de std :: exception avec un paramètre qu'il ne connaît pas, dans ce cas un pointeur vers un tableau de caractères.

#include <stdexcept> 
#include <string> 

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

Serait probablement ce que vous voulez. Pour plus d'informations sur les exceptions, consultez C++ FAQ Lite article on Exceptions et exceptions article sur cplusplus.com.

Bonne chance!

+0

Les gardes d'en-tête sont plus corrects et portables, mais si vous savez que le code doit être compilé avec les compilateurs MS, #pragma fois vous obtiendra une compilation plus rapide (il n'a pas encore l'analyser pour trouver le #endif correspondant). –

+0

Il a précisé qu'il exécute ceci sur Ubuntu, donc je suppose que c'est GCC. Dans ce cas, la déclaration PRAGMA ne fonctionne pas en premier lieu. –

+7

Je suis à peu près sûr que #pragma once est supporté par la version gcc qui était en cours quand ce commentaire a été écrit. Si ce n'est pas le cas, il est supporté maintenant - http://gcc.gnu.org/onlinedocs/gcc-4.6.2/cpp/Alternatives-to-Wrapper-_0023ifndef.html – Steve

9

std :: exception ne dispose pas d'un constructeur qui prend une sorte de chaîne, seule une méthode virtuelle que() qui retourne la description de l'exception.

Vous devrez stocker la chaîne vous-même et la renvoyer à partir de là.

5

Le constructeur de std :: exception ne prend pas d'argument de chaîne. Vous essayez de lui donner un, ce qui provoque l'erreur de compilation.

Vous devez stocker votre chaîne, qu'il vaudrait mieux gérer comme une chaîne std :: string plutôt qu'un pointeur brut, et la renvoyer depuis la méthode what().

2

En regardant la déclaration de la classe d'exception dans MS VS2K5, le constructeur que vous voulez est:

exception (const char *const&); 

alors essayez de changer votre constructeur à:

WrongParameterException (const char *const message) 

et voir si cela aide. Sinon, stockez le pointeur dans votre propre classe et implémentez toutes les méthodes appropriées.

1

Une solution simple consiste à concevoir différemment votre exception. Voici un exemple simple:

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

    CString m_strError; 
}; 

Ensuite, vous pouvez simplement utiliser votre message d'exception comme bon vous semble. En effet, Exception n'a pas de constructeur qui exclut une chaîne, vous devez donc la créer vous-même.

8

Mon conseil serait:

  1. Hériter de std::runtime_error. Comme conseillé par X-Istence ci-dessus. Il s'agit conceptuellement d'une erreur d'exécution, et le constructeur std::runtime_error accepte un std::string comme argument décrivant ce qui s'est passé.
  2. À propos de votre attraper l'exception. J'utiliserais catch(WrongParameterException const& e) (notez la référence const) au lieu de catch(WrongParameterException e), parce que d'abord, l'exception est normalement constante dans votre cas, et, aussi, en utilisant la référence, vous attrapez n'importe quelle sous-classe de WrongParameterException au cas où votre code évolue avec un peu plus raffiné gestion des exceptions.