Given the following classes:
#include <iostream>
using std::ostream;
class MatrixException: public std::exception {
public:
virtual ~MatrixException() {
}
virtual const char* what() throw ()const = 0; // error1 , error2
};
class BadDims: public MatrixException {
public:
const char* what() throw ()const override {
return "Bad dimensions";
}
};
Can someone explain me why I get the following errors?
expected ';' at end of member declaration
expected unqualified-id before '=' tokenov
What #VTT and the other guys said, BUT, std::exception::what is declared noexcept so you shouldn't be promising / threatening to throw anything in the first place.
Therefore, the code should look like this (after a bit of tidying up)
#include <exception>
class MatrixException : public std::exception {
public:
virtual ~MatrixException() { }
virtual const char* what() const noexcept = 0;
};
class BadDims : public MatrixException {
public:
const char* what() const noexcept override { return "Bad dimensions"; }
};
What mystifies me is why the OP's code compiles at all. Perhaps someone older (if that is possible) and wiser (err, ditto) can explain that to me.
Live demo.
Related
I wrote the following code:
class GameException : public mtm::Exception {
};
class IllegalArgument : public GameException {
public:
const char *what() const noexcept override {
return "A game related error has occurred: IllegalArgument";
}
};
class IllegalCell : public GameException {
public:
const char *what() const noexcept override {
return "A game related error has occurred: IllegalCell";
}
};
How may I use inheritance here to prevent some code duplication? As you can see I'm returning the same sentence but with different ending (Which is the class name).
I though about implementing GameException as the following:
class GameException : public mtm::Exception {
std::string className;
public:
const char *what() const noexcept override {
return "A game related error has occurred: "+className;
}
};
But how may I change the value of className for the rest of my classes?
Plus, I'm getting the error:
No viable conversion from returned value of type
'std::__1::basic_string' to function return type 'const char *'
The error is because char [] + std::string yields a std::string but the method is delcared to return a const char *.
To avoid problems with returning a pointer to temporary, I would suggest this:
class GameException : public mtm::Exception {
std::string message;
public:
GameException(const std::string& pref)
: message("A game related error has occurred: " + pref)
{}
const char* what() const noexcept override {
return message.c_str();
}
};
Derived classes then only need
struct some_excpetion : GameException {
some_exception() : GameException("some_exception") {}
};
PS: Inheriting from std::runtime_error can be more convenient, because it already implements what() and comes with a constructor that takes the message to be returned by what(). You can basically remove your GameException and inherit from std::runtime_error instead.
I'm quite iffy when it comes to C++ std:exception handling. Here's some sample code I found on the web, which I currently use.
class MyBaseException : public std::exception
{
public:
explicit MyBaseException(const std::string & message)
: m_Base(message.c_cstr()) {}
explicit MyBaseException(const char *message)
: m_Base(message) {}
virtual ~MyBaseException() throw () {}
protected:
typedef std::exception m_Base;
};
class MyDerivedException : public MyBaseException
{
public:
explicit MyDerivedException (const std::string & message)
: m_Base(message.c_cstr()) {}
explicit MyDerivedException (const char *message)
: m_Base(message) {}
virtual ~MyDerivedException () throw () {}
protected:
typedef MyBaseException m_Base;
};
Now, what I'd like to do is to automatically prepend every exceptions raised with the following scheme.
Some code raises a MyDerivedException exception with the following:
"original_exception_message"
When the MyDerivedException receives "original_exception_message", I'd like to prepend it with:
"Derived Exception Raised: "
And when MyBaseException receives the MyDerivedException exception, I'd like to prepend it with:
"Base Exception Raised: "
Such that the final message would look like this:
"Base Exception Raised: Derived Exception Raised: original_exception_message"
I gotta feeling I'm going to get all sorts of nasty replies on this, about bad concepts and bad practices... But I don't claim to be an expert.
Note that the prepend messages aren't actually that. They would be a little more informative.
Thanks in advance.
#include <iostream>
#include <exception>
class MyBaseException : public std::exception
{
public:
explicit MyBaseException(const std::string & message)
: m_message("Base Exception Raised: " + message) {}
virtual const char* what() const throw ()
{
return m_message.c_str();
}
private:
const std::string m_message;
};
class MyDerivedException : public MyBaseException
{
public:
explicit MyDerivedException (const std::string& message)
: MyBaseException("Derived Exception Raised: " + message) {}
};
int main()
{
try
{
throw MyDerivedException("derived");
}
catch(std::exception const& e)
{
std::cout << e.what();
}
return 0;
}
And read this link http://en.cppreference.com/w/cpp/error/exception
I have this piece of code:
class object
{
public:
virtual ~object(){ }
bool equals(const object& J)const
{
return &J == this;
}
int operator==(const object& J)const
{
return equals(J);
}
virtual int getHash()const;
virtual void getType()const;
void* operator new(size_t size)
{
void*mem = malloc(size);
return mem;
}
};
class notcopyable
{
private:
notcopyable(const notcopyable&){}
notcopyable& operator=(const notcopyable&){}
public:
notcopyable(){}
};
class exception :
public object,public notcopyable
{
private:
public:
virtual ~exception();
virtual const char* info();
};
class exception_not_implemented :
public exception
{
public:
exception_not_implemented()
{
}
virtual const char* info()
{
return "exception_not_implemented: ";
}
};
class exception_oob :public exception
{
public:
exception_oob()
{
}
virtual const char* info()
{
return "Index out of boundary";
}
};
There are two functions throw exception_not_implemented:
void object::getType()const
{
throw exception_not_implemented();
}
int object::getHash()const
{
throw exception_not_implemented();
}
And getting this error:
error C2248: 'js::notcopyable::notcopyable' : cannot access private member declared in class 'js::notcopyable'
The output of the compiler says:
This diagnostic occurred in the compiler generated function 'js::exception::exception(const js::exception &)'
If I delete the two throw shown above, it works well. But the same error doesn't happens to exception_oob. I can't figure out why.
You can temporarily add a private copy constructor declaration, which will generate an error at the point where a copy is being made. Then you can fix that code to not make copies.
The error should happen at other place where you call the (private) copy constructor.
For example:
Exception a;
Exception b = a; // error : cannot access private member ...
I have a base and a derived exceptions, public inner classes of store:
//base class - ProductException
class ProductException: exception
{
protected:
const int prodNum;
public:
//default+input constructor
ProductException(const int& inputNum=0);
//destructor
~ProductException();
virtual const char* what() const throw();
};
//derived class - AddProdException
class AddProdException: ProductException
{
public:
//default+input constructor
AddProdException(const int& inputNum=0);
//destructor
~AddProdException();
//override base exception's method
virtual const char* what() const throw();
};
this function which throws the derived exception:
void addProduct(const int& num,const string& name) throw(AddProdException);
void Store::addProduct( const int& num,const string& name )
{
//irrelevant code...
throw(AddProdException(num));
}
and a function which calls the function and tries to catch an exception:
try
{
switch(op)
{
case 1:
{
cin>>num>>name;
st.addProduct(num,name);
break;
}
}
}
...
catch(Store::ProductException& e)
{
const char* errStr=e.what();
cout<<errStr;
delete[] errStr;
}
The derived class should get caught, but I keep getting the error "unhandled exception". Any ideas why? Thanks!
The reason is that AddProdException is not a ProductException, because you are using private inheritance:
class AddProdException: ProductException {};
You need to use public inheritance:
class AddProdException: public ProductException {};
The same applies to ProductException and exception, assuming the latter is an std::exception.
Without the public keyword, inheritance is considered private by default. This means AddProdException is-not a ProductException. Use public inheritance like so:
class AddProdException : public ProductException
{
public:
//default+input constructor
AddProdException(const int& inputNum=0);
//destructor
~AddProdException();
//override base exception's method
virtual const char* what() const throw();
};
Also, inherit from std::exception publicly in ProductException as well, otherwise you won't be able to catch std::exceptions either (or even better, from std::runtime_error).
I have made my own exception class which derives from runtime_error and is getting an int in the c'tor.
I would like to make a base class for this exception, in order to use polymorphism, so I could catch only the base class and basically I would be catching the derived class, and then call .what() method from it.
So, this is the base class: (ofc in another cpp file I got baseException::~baseException(){})
class baseException
{
virtual ~baseException()=0 {}
virtual const char* what()=0;
};
And this is the derived class:
class myException: public runtime_error, public baseException
{
public:
myException(int): runtime_error("Error occured") {}
const char* what() {return runtime_error::what();}
};
But when in the main I write:
catch(baseException* x)
{
cout<<x->what();
}
it just skips it and does not enter the block, even though myException inherits from baseException. Any suggests?
You should catch exceptions by reference (or const reference), not by pointer.
Your baseException doesn't have the what method, you should probably just derive baseException from runtime_error.
class baseException : public runtime_error
{
public:
baseException(const std::string& what) : runtime_error(what) {}
};
and then
class myException: public baseException
{
public:
myException(int): baseException("Error occured") {}
};
Although I prefer the following idiom:
class myException: public baseException
{
public:
myException(int x): baseException(getWhatMessage(x)) {}
private:
static std::string getWhatMessage(int x) { /*generate the message*/ }
};
On the catch part. If you throw using throw myException(5), then you should catch like this
catch(baseException& x)
{
cout<<x.what();
}
Your catching a reference to a baseException object; therefor you just know the methods of that class. baseException does not have a member called what() though. This causes the error.
Make baseException derive from runtime_error or catch a myException directly.
Edit:
This snippet shows that theres absolutely no reason why pointers shouldnt work together with exceptions:
#include <iostream>
#include <string>
class A {
public:
virtual int test() = 0;
};
class B : public A {
public:
virtual int test() {
return 42;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
try {
throw new std::string("foo");
} catch (std::string* ecx){
std::cout << *ecx << std::endl;
}
try {
throw new B();
} catch (A* ecx) {
std::cout << ecx->test() << std::endl;
}
}
Output:
foo
42
UPDATE: this answer was based on the original version of the question. It now seems that the problem isn't calling what() (as you've worked around that by redeclaring it in your base class). The problem is simply that you're trying to catch a pointer and (I guess) throwing a value; the solution is to catch by reference:
catch (myException const & ex) {
std::cerr << ex.what() << std::endl;
}
(assuming you fix your declaration of what() to be const; if for some reason you really need it to be non-const, then remove const from the catch line).
ORIGINAL ANSWER describing how to call what() if it isn't declared in baseException:
I want to catch baseException*
You'd be better off catching baseException const &; there's no sensible way to throw a pointer.
and call their .what() methods
If you want to call what() , then you might be better off catching std::exception const & instead; unless you also want some functionality from your base class. In that case, perhaps your base class should inherit from std::runtime_error; or perhaps it should inherit from std::exception, in which case your myException type would need to use virtual inheritance.
If you really want to access what() from your classes as they stand, then you'll need to cross-cast to std::exception:
catch (myException const & ex) {
std::cerr << dynamic_cast<std::exception const &>(ex).what() << '\n';
}