9

I have a C++ class and I am trying to run it in 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

when I try to compile it, the compiler gives me this 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&)

Can anyone tell me what am I doing wrong? I tried changing the message variable to string or const string or const string& but it didn't help.

Here is how I use the new exception that I created from 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());
}
Keith Pinson
  • 7,162
  • 5
  • 54
  • 97
  • 3
    Unrelated to the question, but important: do not `use namespace std;` in a header. Second, learn about the standard exception classes C++ provides (std::runtime_error, logic_error, and domain_error etc.). Catch by const&. And don't include for an exception header. – gimpf Feb 23 '09 at 11:48

6 Answers6

19

First, #pragma once is the wrong way to go about it, learn about header include guards. Related question on SO explains why using #pragma once is the wrong way to go about it. Wikipedia explains how to use include guards which serve the same purpose without any of the downsides.

Second, you are calling the constructor of std::exception with a parameter it does not know, in this case a pointer to a character array.

#include <stdexcept>
#include <string>

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

Would probably be what you want. For more information on exceptions, check out C++ FAQ Lite article on Exceptions and the exceptions article at cplusplus.com.

Good luck!

Community
  • 1
  • 1
X-Istence
  • 15,338
  • 6
  • 52
  • 73
  • Header guards are more correct and portable, but if you know the code is to be compiled with the MS compilers, then #pragma once will get you faster compilation (it doesn't have the parse the file again to find the matching #endif). – Michael Kohne Feb 23 '09 at 15:00
  • He specified that he is running this on Ubuntu, so I am assuming that is GCC. In which case the PRAGMA statement does not work in the first place. – X-Istence Feb 24 '09 at 21:30
  • 7
    I'm pretty sure #pragma once is supported by the gcc version that was current when this comment was written. If not, its supported now - http://gcc.gnu.org/onlinedocs/gcc-4.6.2/cpp/Alternatives-to-Wrapper-_0023ifndef.html – Steve Nov 30 '11 at 18:20
  • Even if GCC supports it, that does not mean alternate compilers support it. Not using `#pragma once` is a good idea. – X-Istence Dec 01 '11 at 05:02
  • 4
    `#pragma once` is [pretty widely supported](http://en.wikipedia.org/wiki/Pragma_once#Portability). Also, my ancient corporate environment uses GCC 3.4.2 and `#pragma once` is supported per my testing. – Ross Rogers Aug 03 '12 at 17:52
  • 1
    #pragma once works on MSVC, gcc and clang, use it! Duplicated macros for the manual way can cause a build nightmare – paulm May 25 '15 at 16:04
  • The Header Guard site you linked, http://graphics.cs.niu.edu/people/duffin/csci241/c241man/node90.html is down. – luckydonald Jun 07 '16 at 19:29
  • @luckydonald You are correct, and it seems that the wayback machine didn't keep a copy either :-( – X-Istence Jun 10 '16 at 01:53
  • @luckydonald: Here's a SO that specifies why not to use pragma once: http://stackoverflow.com/a/34884735/13986 – X-Istence Jun 10 '16 at 01:58
9

std::exception does not have a constructor that takes any kind of string, only a virtual what() method that returns the exception description.

You will have to store the string yourself and return it from there.

Timbo
  • 25,571
  • 10
  • 45
  • 70
8

My advice would be:

  1. Inherit from std::runtime_error. As advised by X-Istence above. It is conceptually a runtime error, and also the std::runtime_error constructor accepts a std::string as argument describing what happened.
  2. About your catching the exception. I'd use catch(WrongParameterException const& e) (note the const reference) instead of catch(WrongParameterException e), because first, the exception is normally constant in your case, and, also, using the reference, you catch any subclass of WrongParameterException in case your code evolves with some more refined exception handling.
Diego Sevilla
  • 27,060
  • 3
  • 52
  • 82
5

std::exception's constructor doesn't take a string argument. You're trying to give it one, which is what causes the compile error.

You need to store your string, which would be better to handle as a std::string rather than a raw pointer, and return it from the what() method.

unwind
  • 364,555
  • 61
  • 449
  • 578
2

Looking at the declaration of the exception class in MS VS2K5, the constructor you want is:

exception (const char *const&);

so try changing your constructor to:

WrongParameterException (const char *const message)

and see if that helps. Otherwise, store the pointer in your own class and implement all the relevant methods.

Tim Cooper
  • 144,163
  • 35
  • 302
  • 261
Skizz
  • 64,439
  • 10
  • 63
  • 105
1

A simple solution is to design your exception diferently. Here is a simple example:

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

   CString m_strError;
};

Then you can simply use your exception message as you please. This is because Exception does not have a contructor that excepts a String, so you have to stlre it on your own.

David Božjak
  • 14,847
  • 15
  • 63
  • 97