try-catch with exceptions defined in template class - c++

I'm trying to implement a priority queue using a linked list, but I'm having issues with try/catch. Here are the relevant parts of the priority queue header file:
#ifndef PRIORITYQUEUELINKED_H
#define PRIORITYQUEUELINKED_H
#include "RuntimeException.h"
#include <list>
using namespace std;
template <typename E, typename C> // uses data type and some total order relation
class PriorityQueueLinked {
// code for PriorityQueueLinked
class EmptyPriorityQueueException : public RuntimeException {
public:
EmptyPriorityQueueException() :
RuntimeException("Empty priority queue") {}
};
// more code
#endif
Here is the RuntimeException header file:
#ifndef RUNTIMEEXCEPTION_H_
#define RUNTIMEEXCEPTION_H_
#include <string>
class RuntimeException {// generic run-time exception
private:
std::string errorMsg;
public:
RuntimeException(const std::string& err) { errorMsg = err; }
std::string getMessage() const { return errorMsg; }
};
inline std::ostream& operator<<(std::ostream& out, const RuntimeException& e)
{
out << e.getMessage();
return out;
}
#endif
Here is my main:
#include "PriorityQueueLinked.h"
#include "Comparator.h"
#include <iostream>
using namespace std;
int main() {
try {
PriorityQueueLinked<int,isLess> prique; // empty priority queue
prique.removeMin(); // throw EmptyPriorityQueueException
}
catch(...) {
cout << "error" << endl << endl;
}
getchar();
return 0;
}
My problem lies in not being able to configure a replacement for the "..." for catch. I've tried several things, one of them: "catch(PriorityQueueLinked < int,isLess > ::EmptyPriorityQueueException E)", but in this case it says that EmptyPriorityQueueException is not a member of PriorityQueueLinked. Any advice would be greatly appreciated.
Thanks

Try-catch supports inheritance with exception classes. catch (const RuntimeException & ex) will catch any subclass of RuntimeException, even if its private. This is the whole point of deriving exception classes.
By the way, never write using namespace std; is a header, you can never know who include it, and how. Also the standard library already has your genereal purpose exception class, and what a surprise! They also clall it runtime exception, exception it§s written like this: std::runtime_exception. You can find it in <stdexcept>.

Related

I cant' seem to catch this exception in C++

For some reason the program exits when executed while testing the handling of an exception. This is the class im using as the exception recipient
#ifndef _BADALLOC
#define _BADALLOC
#include <cstring>
using namespace std;
class badalloc{
private:
char* Message;
double Number;
public:
explicit badalloc(char* M="Error",const int & N=0) {strcpy(Message,M); Number=N;}
char* what () const {return Message;}
};
#endif
this is the function member of another class that generates the exception
void ContoCorrente::Prelievo ( const double & P) throw ( badalloc )
{
if(P>0)
{
throw (badalloc ("ERROR 111XX",P));
} ...
test main :
try
{
c2.Prelievo(20);
}
catch ( badalloc e)
{
cout<<e.what()<<endl;
}
output:
Process exited after 1.276 seconds with return value 3221225477
Press any key to continue . . .
i tried defining the badalloc object to throw as "const" but to no use. any ideas?
Very simple, you are copying to an uninitialised pointer Message in your badalloc class.
You'd get this error just by constructing a badalloc object. This has nothing to do with exceptions.
EDIT
Here's a possible solution, using std::string to avoid the pointer problems.
#ifndef _BADALLOC
#define _BADALLOC
#include <string>
class badalloc{
private:
std::string Message;
double Number;
public:
explicit badalloc(const char* M="Error",const int & N=0) : Message(M), Number(N) {}
const char* what () const {return Message.c_str();}
};
#endif

C++ Exception Handling: defining exception as object

I am incredibly new to C++ and I have an assignment to create a test program for exception handling. I am having problems catching the exceptions, both those defined in the given classes and those I have defined in main. Could someone look over what I have and point out where I'm going wrong?
From the professor:
#ifndef STUDENT_H
#define STUDENT_H
#include <string>
using namespace std;
class Student
{
public:
Student();
Student(string thisStudentID);
void enroll(string thisSectionID);
private:
string studentID;
bool timeToThrow();
static int sneakyCount;
};
#endif
#include <string>
#include <iostream>
#include "Student.h"
#include "StudentException.h"
using namespace std;
// The constructor for this class accepts a Student ID
Student::Student(string thisStudentID)
{
// This first statement updates a variable used to help decide when to Throw an Exception
sneakyCount++;
// Any text will be accepted as the student ID in this implementation
if (!timeToThrow())
studentID = thisStudentID;
else
throw StudentException("Student " + thisStudentID + " has been expelled from this school");
}
// This default constructor shouldn't be used, so throwing an exception isn't so artificial, its
// the right thing to do. We will also find out if this constructor gets called at time that we don't expect.
Student::Student()
{
// This first statement updates a variable used to help decide when to Throw an Exception
sneakyCount++;
throw StudentException("Incorrect Call to Student Constructor - No Student ID Provided");
}
// This dummy function would enroll the student in a course
void Student::enroll(string thisSectionID)
{
// This first statement updates a variable used to help decide when to Throw an Exception
sneakyCount++;
if (!timeToThrow())
cout << endl << "Student: " << studentID << " is now enrolled in " << thisSectionID << endl;
else
throw StudentException("Section " + thisSectionID + " has been cancelled");
return;
}
// This is the code that helps decide when to throw an exception. You are welcome to look at it,
// but its only here to help generate unexpected exceptions. It will vary in different versions of Student
// as I play around with it.
int Student::sneakyCount = 0;
bool Student::timeToThrow()
{
if (sneakyCount == 4)
return true;
else
return false;
}
#ifndef STUDENTEXCEPTION_H
#define STUDENTEXCEPTION_H
#include <string>
using namespace std;
class StudentException
{
public:
StudentException(string thisErrorMessage);
string errorMessage();
private:
string message;
};
#endif
#include <string>
#include "StudentException.h"
using namespace std;
StudentException::StudentException(string whatWentWrong)
{
// Set the stored message within the object
// Any text will be accepted as the error message
message = whatWentWrong;
}
// Return the error message stored inside the object
string StudentException::errorMessage()
{
return message;
}
My code for the test program:
#include <iostream>
#include <string>
#include "StudentException.h"
#include "Student.h"
using namespace std;
int main()
{
char again = 'n';
do
{
try
{
Student testStudent1("S0000001");
testStudent1.enroll("CSC-160-500");
}
catch(StudentException())
{
StudentException testException1("Pre-requisites required");
cout << testException1.errorMessage();
}
cout << "Again?\n";
cin >> again;
}
while(tolower(again) == 'y');
return 0;
}
I only have the loop for easier testing as the Exception throwing is somewhat random. I only catch exceptions if I use catch(...). Any hints on what I'm doing wrong?
catch(StudentException())
{
StudentException testException1("Pre-requisites required");
cout << testException1.errorMessage();
}
That's not the way to do it. Your catch doesn't catch the actual exception, you should make it an argument :
catch(const StudentException& ex)
{
cout << ex.errorMessage();
}
catch(StudentException()) tries to catch a function type. You want
catch (StudentException& se)
(and then you can use se in the handler instead of constructing a new unrelated StudentException.)
catch(StudentException()) {
...
}
This is the wrong syntax. You need to say
catch(const StudentException& e) {
...
}
While we're here, it's usually a good idea for exceptions to inherit from one of the standard library's exception classes, for example
class StudentException : public std::runtime_error
{
public:
StudentException(const string& thisErrorMessage)
: std::runtime_error(thisErrorMessage)
{}
};
Not only does is this easier to implement, but it also provides the what() member function, which people will usually look for to find the exception message.

C++ Exceptions and handling

I am new to writing exceptions in c++ and I am struggling with an error. I won't get very much into detail 'cause I don't think this is relevant for the problem that I have.
#ifndef _STUDENT_H_
#define _STUDENT_H_
#include <string>
#include <map>
#include <vector>
#include <stdexcept>
#include <iostream>
class NoMarkException: public exception
{
public: NoMarkException():exception(){
cout<< "No marks were found." << endl;
}/*
NoMarkException(const string &name){
cout << "No marks for " << name << " were found."<< endl;
}*/
};
#endif
This is my NoMarkException class
float Student::getMaxMark() const throw(NoMarkException) {
if (marks.empty()) {
throw NoMarkException::NoMarkException();
}
float final = 0;
for (it = marks.begin(); it != marks.end(); it++) {
if ((*it).second > final) {
final = (*it).second;
}
}
return final;
}
And this is my Student.cpp
When I am building the project I get error: cannot call constructor 'NoMarkException::NoMarkException' directly
Any ideas why it is causing the problem?
if (marks.empty()) {
throw NoMarkException();
}
The error you get does not actually have anything to do with the fact you're using an exception class. The problem is that you're trying to instantiate an object of class NoMarkException by explicitly calling the (default) constructor, NoMarkException::NoMarkException(). In C++ you don't call constructors explicitly; rather, when you define a new variable, an appropriate constructor gets called. For example
void foo() {
std::vector<int> v(5);
NoMarkException my_exception();
NoMarkException my_other_exception();
}
or, using equivalent but more appropriate due to recent language changes:
void foo() {
std::vector<int> v { 5 };
NoMarkException my_exception { };
NoMarkException my_other_exception { };
}
In this case (both syntax alternatives), the constructors:
std::vector<int>::vector(std::vector<int>::size_type count)
NoMarkException::NoMarkException()
NoMarkException::NoMarkException()
are called (*).
In your case, you simply need to replace the explicit call you make to NoMarkException::NoMarkException() in the throw with an instantiation of NoMarkException object, i.e. your statement will be:
throw NoMarkException();
(*) - actually, the vector constructor that's called has a few more parameters which take their default values. See here.

Replace LOG(fatal) by an exception

I'm currently using caffe but I'm facing a problem. Sometime the library call LOG(FATAL) but I would like to raise an exception and catch it.
I have tried to do my own class defined as below:
#include <stdexcept>
#include <iostream>
#include <sstream>
class FatalException
{
private:
std::stringstream _ss;
public:
template<typename T>
std::ostream& operator<<(const T& obj){
_ss << obj;
return _ss;
}
~FatalException(){
throw std::runtime_error(_ss.str().c_str());
}
};
The problem is that when I'm doing some testing such as
int main() {
try {
FatalException() << "test";
}
catch(...) {
std::cout << "here" << std::endl;
}
}
the exception is thrown after the try scope
Do you have any hints?
Should I overload a stream class and throw an exception when the stream is flushed?

Printing name of the initializing function for a class

Is it possible to capture and print name of the function which initialized a class object? What I want is something like this:
class MyException: public std::exception
{
public:
MyException(const std::string message, const std::string caller = __func__)
: _caller(caller),
_msg(message)
{
...
}
std::string what(void); // prints messaged along with the caller
private:
...
}
In the above class MyException I want the caller to capture the function name where an object was instantiated so that user is warned of which function threw. I can always do
...
throw MyException(message, __func__);
...
while removing the default __func__. But then I am doing this trivial thing every time I instantiate an MyException object.
Is there a better way to instruct user exactly which function throws?
Thanks in advance,
Nikhil
If I wanted to provide automatic context for my exceptions I'd do it like this:
#include <iostream>
#include <stdexcept>
#include <string>
struct context_info {
explicit context_info(std::string function)
: _function { std::move(function) }
{}
// perhaps the context info will increase later to include class and instance?
friend std::string to_string(const context_info& ci)
{
return ci._function;
}
private:
std::string _function;
};
struct my_exception : std::runtime_error
{
my_exception(const std::string& message)
: std::runtime_error(message)
{}
my_exception(context_info context, const std::string& message)
: my_exception(message + " called from " + to_string(context))
{}
// everything else already taken care of for you
};
#if defined(NDEBUG)
#define THROW_WITH_CONTEXT(TYPE, ...) throw TYPE(__VA_ARGS__)
#else
#define THROW_WITH_CONTEXT(TYPE, ...) throw TYPE(context_info(__func__), __VA_ARGS__)
#endif
using namespace std;
void do_foo()
try {
THROW_WITH_CONTEXT(my_exception, "foo failure");
}
catch(const exception& e) {
cout << e.what() << endl;
}
int main() {
// your code goes here
try {
do_foo();
THROW_WITH_CONTEXT(my_exception, "error");
}
catch(const exception& e) {
cout << e.what() << endl;
}
return 0;
}
expected output:
foo failure called from do_foo
error called from main
However, neat as this is it's probably not what you should really be doing as it won't provide you with enough context in a large complex program.
have a look at the documentation for std::throw_with_nested etc. You can catch an exception at each stage of the call stack and re-throw it with additional context information. This is much more useful.
http://en.cppreference.com/w/cpp/error/throw_with_nested