Solved

Am I using exceptions correctly?

Posted on 2004-04-02
17
213 Views
Last Modified: 2010-04-01
Hello

Im writing a linked list where some operations must use exceptions.

My exception class looks like this:

#include <stdexcept>
#include <string>
using std::string;
using std::out_of_range;

class ListError : public out_of_range
{
public:
    ListError(const string& str = "") : out_of_range(str){}

private:
    string str;
};
#endif


*************************************************
In main I have a menu where u can do a lot of operations on the list.
One of them is called first(), which sets the current pointer to point at
the first element. If no element has been inserted an exception must be thrown.

void List::first() throw (ListError)
{
    if (!isEmpty())
        current = firstNode;
    else
        throw ("Error");                                
}

So, I call first() without having inserted any elements before.
The message I get from Borland Builder i not "Error" as in "throw ("Error");"
Instead I get "..... raised exception class char* with message 'Exception Object Adress:
0x955C6A'. Process stopped. Use step or run to continue."


So, where is my "Error"?
What am I doing wrong?

Thanks / Martin








0
Comment
Question by:martinsmith34
  • 6
  • 3
  • 2
  • +2
17 Comments
 
LVL 10

Expert Comment

by:Sys_Prog
ID: 10739855
Go thru the follwing code

#include <iostream>
#include <string>
#include <sstream>
#include <stdexcept>

using namespace std ;

class ListError {
      public:
          ListError(const string& str1 = "") : str ( str1 ) {}
      
      private:
          string str;
};

int f () throw (ListError) {
      throw ListError ( "Error" );                                
}

int main(int argc, char* argv[])
{
       try {
       f () ;
    }
    catch ( ListError e ) {
          cout << "Error" ;
    }  
      system("pause");
      return 0;
}


Amit
0
 
LVL 10

Expert Comment

by:Sys_Prog
ID: 10739924
Using your way of inheriting from out_of_range


#include <iostream>

#include <stdexcept>

using namespace std ;

class ListError : public out_of_range
{
      public:
          ListError(const string& str1 = "") : out_of_range(str1), str ( str1) {}
          ~ListError () throw () {
         }
      private:
          string str;
};

int f () throw (ListError) {
      throw ListError ( "Error" ) ;                                
}

int main(int argc, char* argv[])
{
       try {
       f () ;
    }
    catch ( ListError e ) {
          cout << "Error" ;
    }  
      system("pause");
      return 0;
}
0
 
LVL 10

Expert Comment

by:Sys_Prog
ID: 10739938
Here are the base class declarations

  /** This represents an argument whose value is not within the expected
   *  range (e.g., boundary checks in basic_string).  */
  class out_of_range : public logic_error   {
      public:
           explicit out_of_range(const string&  __arg);
  };


  class logic_error : public exception   {
            string _M_msg;

       public:
           /** Takes a character string describing the error.  */
          explicit logic_error(const string&  __arg);
          virtual ~logic_error() throw();

          /** Returns a C-style character string describing the general cause of
           *  the current error (the same string passed to the ctor).  */
           virtual const char*
           what() const throw();
  };


HTh

Amit
0
 

Author Comment

by:martinsmith34
ID: 10740628
Thanks for replying



The message I get is the same as I described earlier.......
0
 

Expert Comment

by:duncanlatimer
ID: 10740797
Your are throwing a char * because you throw( "zzzz" ) you need to throw ListError( "zzzz" )
0
 
LVL 16

Expert Comment

by:George Tokas
ID: 10741139
try
throw Exception("Error");

gtokas
0
 
LVL 10

Expert Comment

by:Sys_Prog
ID: 10742571
In my above post I have made 2 corrections to your code

1. Declared the virtual Destructor for ur exception class
2. The throw statement should throw an object of ur exception class. THus, if u use just throw ("Error" ) ;
then it will search for a Exception class of Type char * OR std::string
However, in your catch statement, u must have caught Exception of type of ur class (as shown in my example), thus u should throw an object of type ur exception class (as shown in my example)

Also, Post ur complete code, i.e. the code where u have used try & catch statements, so that we could help better

HTH

Amit
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 10

Expert Comment

by:Sys_Prog
ID: 10742585
In my above post I have made 2 corrections to your code

1. Declared the virtual Destructor for ur exception class
2. The throw statement should throw an object of ur exception class. THus, if u use just throw ("Error" ) ;
then it will search for a Exception class of Type char * OR std::string
However, in your catch statement, u must have caught Exception of type of ur class (as shown in my example), thus u should throw an object of type ur exception class (as shown in my example)

Also, Post ur complete code, i.e. the code where u have used try & catch statements, so that we could help better

HTH

Amit
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 10743246
You can use what() to get the message.

e.g.
--------8<--------
#include <iostream>
#include <stdexcept>

struct ListError : public std::out_of_range
{
        ListError(const string& str = "ListError: out of range") : out_of_range(str) {}
};

int oops_a_daisy() throw (ListError)
{
     throw ListError();                                
}

int main()
{
        try {
                oops_a_daisy() ;
                std::cout << "Life goes on\n";
        }
        catch (ListError e) {
                std::cout << "Error: " << e.what() << '\n';
        }  
}
--------8<--------
0
 

Author Comment

by:martinsmith34
ID: 10746815
I have got some good tips from you all now.

I have updated the code but the problem remains.
Could this be an BB6 problem rather than code problem?


***Exception class***

#include <stdexcept>
#include <string>
using std::string;
using std::out_of_range;

class ListError : public out_of_range
{
public:
    ListError(const string& str = "") : out_of_range(str){}

private:            
    string str;      
};
#endif


***List.cpp***

void List::first() throw (ListError)
{
    if (!isEmpty())
        current = firstNode;
    else
        throw ListError("Error");  
}

***Main.cpp***

case 8: try
                    {
                        myList.first();
                    }
                    catch (ListError error)
                    {
                        cout << error.what() << endl;
                    }
                    break;




Maybe I should try another complier to see if the message pops up?

Thanks /
0
 
LVL 10

Accepted Solution

by:
Sys_Prog earned 43 total points
ID: 10746930
I have never used BB6 but I think u should try some other compiler

A good free compiler + editor is avaiable at the following link

http://www.bloodshed.net/devcpp.html

Amit
0
 
LVL 16

Assisted Solution

by:George Tokas
George Tokas earned 41 total points
ID: 10747419
I AM using BCB Martin...
Anyway WHERE is the problem??
if you use:

throw Exception(YourExceptionMessageHere);

this will work.
"Exception" is the native VCL type trapped and displayed by any application developed on BCB.
If you want that ONLY to work properly ( this code you give I mean ) then you will not have any problem. When the exception is throwed then you will have the message:
Application....raised exception with message "YourExceptionMessageHere"..

Those were about exception throwing with BCB in general.

If you want to raise custom exception from a component you are making then there are some more techniques.
Anyway at the code you are using I think the approach I'm giving you will do the work.
P.S. Check if the exception is throwed and the message OUTSIDE the BCB IDE.
I mean build the application for "release" and run the exe BCB makes.

Regards,
gtokas.
0
 
LVL 17

Assisted Solution

by:rstaveley
rstaveley earned 41 total points
ID: 10747744
martinsmith34,

Sys_Prog and I both provided you with complete code for standalone applications, which ought to demonstrate the exception handler. You've reported the error in terms of exerpts from your own program, which makes it tricky to establish whether the problem was the exception handling or something somwhere else in your application. Are you able to get your set-up to build one of the complete listings above, and if so does it display the error message OK? I don't use Borland C++ builder (though I used to be faithful to Borland from Turbo C version 1.0 up to Borland C++ Version 4.5); it would be valuable to see if any other BCB users are able to build and use one of the these demos satisfactorily. That would establish if your problem is BCB-related or something somewhere else in your application.
0
 
LVL 16

Expert Comment

by:George Tokas
ID: 10757747
Sys_Prog and rstaveley are right.
Their recomendation are as rstaveley describe.
About BCB now:
The application's cpp looks like this:
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
        try
        {
                 Application->Initialize();
                 Application->CreateForm(__classid(TForm1), &Form1);
                 Application->Run();
        }
        catch (Exception &exception)// HERE BCB DEALS WITH EXCEPTIONS.
        {
                 Application->ShowException(&exception);
        }
        return 0;
}
And that was why I recomended to use:
throw Exception(YourExceptionMessage);
IF you are making a new component and want to throw or handle its exceptions in a class or something then you need to use other approach..
If you just want to make it work you can throw the exception as I described and customize the message.

regards,
gtokas.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now