Создание нового исключения в C ++ - PullRequest
9 голосов
/ 23 февраля 2009

У меня есть класс C ++, и я пытаюсь запустить его в Ubuntu:

#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

когда я пытаюсь его скомпилировать, компилятор выдает мне эту ошибку:

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

Может кто-нибудь сказать мне, что я делаю не так? Я попытался изменить переменную сообщения на string или const string или const string&, но это не помогло.

Вот как я использую новое исключение, которое я создал из main:

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());
}

Ответы [ 6 ]

18 голосов
/ 23 февраля 2009

Во-первых, #pragma once - неправильный путь, узнайте о заголовках, включая охранников. Связанный вопрос по SO объясняет, почему использование #pragma once является неправильным способом решения этой проблемы. Википедия объясняет, как использовать , включая охранников , которые служат той же цели без каких-либо недостатков.

Во-вторых, вы вызываете конструктор std :: exception с параметром, которого он не знает, в данном случае указатель на массив символов.

#include <stdexcept>
#include <string>

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

Возможно, это то, что вы хотите. Дополнительные сведения об исключениях см. В статье C ++ FAQ Lite об исключениях и статье об исключениях на cplusplus.com.

Удачи!

9 голосов
/ 23 февраля 2009

std :: exception не имеет конструктора, который принимает какую-либо строку, только виртуальный метод what (), который возвращает описание исключения.

Вам нужно будет самостоятельно сохранить строку и вернуть ее оттуда.

8 голосов
/ 23 февраля 2009

Мой совет будет:

  1. Наследовать от std::runtime_error. Как рекомендовано X-Istence выше. Концептуально это ошибка времени выполнения, и конструктор std::runtime_error принимает std::string в качестве аргумента, описывающего то, что произошло.
  2. О том, что вы поймали исключение. Я бы использовал catch(WrongParameterException const& e) (обратите внимание на константную ссылку) вместо catch(WrongParameterException e), потому что во-первых, исключение обычно является константой в вашем случае, а также, используя ссылку, вы перехватываете любой подкласс WrongParameterException в случае код развивается с более усовершенствованной обработкой исключений.
5 голосов
/ 23 февраля 2009

Конструктор std :: exception не принимает строковый аргумент. Вы пытаетесь дать ему один, который является причиной ошибки компиляции.

Вам необходимо сохранить вашу строку, которую лучше обрабатывать как std :: string, а не как необработанный указатель, и вернуть ее из метода what().

2 голосов
/ 23 февраля 2009

Глядя на объявление класса исключений в MS VS2K5, вам нужен конструктор:

exception (const char *const&);

, поэтому попробуйте изменить конструктор на:

WrongParameterException (const char *const message)

и посмотрим, поможет ли это. В противном случае сохраните указатель в своем собственном классе и реализуйте все соответствующие методы.

1 голос
/ 23 февраля 2009

Простое решение состоит в том, чтобы разработать свое исключение по-другому. Вот простой пример:

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

   CString m_strError;
};

Тогда вы можете просто использовать свое сообщение об исключении по своему усмотрению. Это связано с тем, что в Exception нет конструктора, который исключает строку, поэтому вы должны создать его самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...