Throwing exceptions in C++

Started by
4 comments, last by mattd 14 years, 5 months ago
I haven't used try/catch blocks very often so I am very rusty on how to do these types of things. Anyway I have an exception class set up and a class that has operations that throw the exceptions. This is just meant as an exercise to remind me how exceptions are used. Anyway here is my code. Exception class

#include <stdexcept>
#include <string>

using namespace std;

class TimeException: public logic_error
{
public:
	TimeException(const string & message = ""): logic_error(message.c_str())
	{}
};

Header file for time class

#ifndef TIME_H
#define TIME_H

#include "TimeException.h"

#include <iostream>
using namespace std;

class Time
{
public:
	Time();
	// Default constructor sets time to 0 hour and 0 minute

	Time(int h, int m);
	// Constructor that sets hour = h, and minute = m

	int getHour() const;
	// Returns hour

	void setHour(int h) throw(TimeException);
	// sets the hour = h
	// Precondition: h >= 0 or h <= 24
	// Postcondition: if h not within range program throws
	// exception

	int getMinute() const;
	// Returns minute

	void setMinute(int m) throw(TimeException);
	// sets the minute = m
	// Precondition: m >= or m < 60
	// Postcondition: If m not within range program throws
	// exception

	void increaseMinutes(int m) throw(TimeException);
	// Increases the minutes by m minutes
	// Precondition: m > 0
	// Postcondition: The minutes are increased by m minutes, minutes are measured
	// by increments of 60, therefore if m exceeds 60 then hours is incremented as
	// well as minutes appropriately according to 60 minutes = 1 hour

	void display24HourNotation();
	// Displays the 24 hour notation of time

	void display12HourNotation();
	// Displays the 12 hour notation of time
private:
	int hour;
	int minute;
};

#endif

Time.cpp file

#include "Time.h"

Time::Time(): hour(0), minute(0)
{}

Time::Time(int h, int m): hour(h), minute(m)
{}

int Time::getHour() const
{
	return hour;
}

void Time::setHour(int h) throw(TimeException)
{
	if(h < 0 || h > 24)
	{
		throw TimeException("Time Exception: Bad hour on setHour");
	}

	hour = h;
}

int Time::getMinute() const
{
	return minute;
}

void Time::setMinute(int m) throw(TimeException)
{
	if(m < 0 || m >= 60)
	{
		throw TimeException("Time Exception: Bad minute on setMinute");
	}

	minute = m;
}

void Time::increaseMinutes(int m) throw(TimeException)
{
	if(m <= 0)
	{
		throw TimeException("Time Exception: can not increase <= 0 minutes");
	}

	// add m to minute value
	minute += m;

	// need to get the hour correct along side minute
	if(minute >= 60)
	{
		// minute is actually hour now therefore must be
		// changed to have the correct value
		hour += minute / 60; // correct hour value

		minute = minute % 60; // correct minute value
	}

	// need to double check to make sure hour isn't exceeding
	// the 24 hour limit
	hour = hour % 24; // correct hour value
}

void Time::display24HourNotation()
{
	// show time in 24 hour notation
	// hour/minutes stored in 24 hour notation
	// therefore just print time
	if(minute < 10)
		cout << "Time in 24 hour notation is: " << hour << ":0" << minute << endl;
	else
		cout << "Time in 24 hour notation is: " << hour << ":" << minute << endl;
		
}

void Time::display12HourNotation()
{
	// show time in 12 hour notation
	// need to specify between am and pm
	int hour12;

	if(hour >= 12 && hour < 24)
	{
		// your in the PM
		if(hour == 12)
			hour12 = hour;
		else
			hour12 = hour - 12;

		if(minute < 10)
			cout << "Time in 12 hour notation is: " << hour12 << ":0" << minute << " PM\n";
		else
			cout << "Time in 12 hour notation is: " << hour12 << ":" << minute << " PM\n";
			
	}
	else
	{
		int hour12;
		// your in the AM
		if(hour == 24)
			hour12 = 12;
		else
			hour12 = hour;

		if(minute <  10)
			cout << "Time in 12 hour notation is: " << hour12 << ":0" << minute << " AM\n";
		else
			cout << "Time in 12 hour notation is: " << hour12 << ":" << minute << " AM\n";
	}
}

The driver program

#include "Time.h"

int main()
{
	Time t, t2(8,35);
	/*cout << t.getHour() << endl;
	cout << t.getMinute() << endl;
	cout << t2.getHour() << endl;
	cout << t2.getMinute() << endl;*/

	try
	{
		t.setHour(-1);
	}
	catch(TimeException e)
	{
		e.what();
	}
	
	/*cout << t.getHour() << endl;
	t.setHour(32);
	cout << t.getHour() << endl;

	t.setMinute(30);
	cout << t.getMinute() << endl;
	t.setMinute(60);
	cout << t.getMinute() << endl;*/
	
	

	t2.display24HourNotation();
	t2.display12HourNotation();

	t2.increaseMinutes(30);
	//cout << t2.getHour() << endl;
	//cout << t2.getMinute() << endl;
	t2.display24HourNotation();
	t2.display12HourNotation();
	
	return 0;
}

Basically when i execute the try catch block nothing happens with e.what(), which I thought was suppose to print my error message. Just so you know when I put a normal cout statement in the catch block it writes information there so clearly it's making it to the block it's intended to. Any help would be appreciated. Thanks.
Advertisement
Looking here, exception::what() actually returns a const char* of the exception message, so you need to actually output it somehow, e.g using std::cout or to a log file.
Ok so I see why e.what() doesn't do anything now but where does the throw TimeException("Time Exception: ... "); output at? I thought when the the try/catch block was done the throw(TimeException e) would output the "Time Exception: ..."); but it doesn't. So basically where does the TimeException("Time Exception: ..."); go after its been thrown.
Exceptions don't output anything -- they're a mechanism for control the flow of execution, like an if statement or a while loop.

If you want them to output something, it's up to you to do that inside your catch block.
After you throw the TimeException (containing your string), your catch block gets access to it and can output the string, if that's what you want it to do.

Just change
	catch(TimeException e)	{		e.what();	}
to
	catch(TimeException e)	{		std::cout << e.what();	}
Quote:
Just change

catch(TimeException e)

{

e.what();

}

to

catch(TimeException e)

{

std::cout << e.what();

}


There we go :), and thanks I was pretty sure they didn't output anything directly to the ostream but I just wanted to know how to double check to see if it was performing correctly. Thanks for everyone's help.
Consider catching by (const) reference instead of value.
try {    // ...} catch (const TimeException& e) {    // ...}

Also, std::logic_error's constructor takes a std::string, doesn't it?
TimeException(const string & message = ""): logic_error(message){}

This topic is closed to new replies.

Advertisement