C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
  #1  
Old February 18th, 2002, 07:05 PM
MJEggertson MJEggertson is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jan 2002
Location: Seattle WA
Posts: 863 MJEggertson User rank is Corporal (100 - 500 Reputation Level)MJEggertson User rank is Corporal (100 - 500 Reputation Level)MJEggertson User rank is Corporal (100 - 500 Reputation Level)MJEggertson User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 22 sec
Reputation Power: 8
Question [C++] try, catch, throw and destructors

Hi, I'm just venturing into error handling in C++ as I try to learn the language, and I had more of a question rather than a problem.

Scenario: I have a very trivial program that first assigns integers to an array, then tries to print them out from a for loop, with the loop purposely going over the array bounds. I handle the error by throwing an exception as an xBoundary class, which I create to hold data about the error.

Implementation: Just for kicks, I made an actual implementation of the the xBoundary class constructors/desctructor, and had them print out a message so I could see what's happening, and where the class is destroyed. Then I noticed that although only one instance of an xBoundary is created, 3 calls to the destructor are made. I also noticed that on each call to the destructor, the class is not actually destroyed, since the data remains when the next call to the destructor is made.

Question: Why are 3 desctructors being called? The code is below, and for simplicity sake, is all in the same file.

Code:
#include <iostream>

class xBoundary
{
public:
    // constructors
    xBoundary();
    xBoundary(const int index);
    ~xBoundary();

    // accessor
    int ErrIndex() const {return myIndex;}
 
private:
    int myIndex;
};

// implementations
// The constructors merely print out a message
// indicating they have bee called, along with
// the value of their myIndex property.
xBoundary::xBoundary():
myIndex(-1)
{
    std::cout << "xBoundary() -> myIndex=" << myIndex << "\n";
}

xBoundary::xBoundary(const int index):
myIndex(index)
{
    std::cout << "xBoundary(const int) -> myIndex=" << myIndex << "\n";
}

xBoundary::~xBoundary()
{
    std::cout << "~xBoundary() -> myIndex=" << myIndex << "\n";
}

int main()
{
    const int defaultSize = 10;
    const int someOtherNumber = 11;
    int myArray[defaultSize];
    for (int i = 0; i < defaultSize; i++)
        myArray[i] = i;
    try
    {
        for (int i = 0; i < someOtherNumber; i++)
        {
            if (i >= defaultSize)
                throw xBoundary(i);
            else
                std::cout << "myArray[" << i << "]:\t" << myArray[i] << "\n";
        }
    }
    catch(xBoundary err)
    {
        std::cout << "Failed to retrieve data at index " << err.ErrIndex() << ".\n";
    }
    return 0;
}


Are the mulitple destructors just being called as the instance of the xBoundary class would normally fall out of scope (but the exception prevents the object from being destroyed)?

Curious,

-Mike

Reply With Quote
  #2  
Old February 20th, 2002, 04:15 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Dev Shed God 5th Plane (7000 - 7499 posts)
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,335 Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level) 
Time spent in forums: 4 Weeks 12 h 27 m 15 sec
Reputation Power: 662
In most books I've read, the exception handler is usually

catch (xBoundary &err)

You can always use:

catch (xBoundary err)

However, in your case, the exception handler catches by value. Hence, a copy of the original exception object is made, which is why you see two constructors and destructors. If you declare the handler to have a reference to the thrown object, then you'll see the constructor fire up only once. Another way, which is used in a lot of code written by Visual C++ programmers goes like this:

Code:
try {
...

   if (i >= defaultSize) 
       throw new xBoundary(i);
...
} catch (xBoundary *err) {
   cout << err->ErrIndex();
   delete err;
}


In this case, you'll see only one constructor and one destructor message. However, you're responsible for deleting your own thrown exception object.

Reply With Quote
  #3  
Old February 20th, 2002, 06:05 PM
MJEggertson MJEggertson is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jan 2002
Location: Seattle WA
Posts: 863 MJEggertson User rank is Corporal (100 - 500 Reputation Level)MJEggertson User rank is Corporal (100 - 500 Reputation Level)MJEggertson User rank is Corporal (100 - 500 Reputation Level)MJEggertson User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 22 sec
Reputation Power: 8
Interesting. Creating the new xBoundary and using pointers does do what is expected: only a single constructor and destructor are called.

My mistake: newbie forgets about copy constructors.

*sigh*

So much to learn.

Reply With Quote
  #4  
Old February 20th, 2002, 06:21 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Dev Shed God 5th Plane (7000 - 7499 posts)
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,335 Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level) 
Time spent in forums: 4 Weeks 12 h 27 m 15 sec
Reputation Power: 662
well, in your code you had:

catch (xBoundary err)

Now with your code, since you're catching by value, the compiler will create a copy of the original thrown object. It'll use the default copy constructor to copy the values from the old object to the new one. You can verify this by adding your own copy constructor to the object.

Code:
class xBoundary
{
 public:
  // constructors
  xBoundary();
  xBoundary(const int index);
  xBoundary(const xBoundary& src); // Overriding the default copy constructor
  ~xBoundary();

  // accessor
  int ErrIndex() const {return myIndex;}

 private:
  int myIndex;
};

// implementations
// The constructors merely print out a message
// indicating they have bee called, along with
// the value of their myIndex property.
xBoundary::xBoundary():
  myIndex(-1)
{
  std::cout << "xBoundary() -> myIndex=" << myIndex << "\n";
}


xBoundary::xBoundary(const int index):
  myIndex(index)
{
  std::cout << "xBoundary(const int) -> myIndex=" << myIndex << "\n";
}

xBoundary::~xBoundary()
{
  std::cout << "~xBoundary() -> myIndex=" << myIndex << "\n";
}

// New copy constructor
xBoundary::xBoundary(const xBoundary& src) {
  myIndex = src.ErrIndex() + 1;
  std::cout << "xboundary(const xBoundary &) " << myIndex << "\n";
}


Notice that in the copy constructor, I'm incrementing the errindex of the original by 1. Try using
catch (xBoundary err)
catch (xBoundary &err)
catch (xBoundary *err)

and observe the differences.

Reply With Quote
  #5  
Old February 20th, 2002, 06:47 PM
MJEggertson MJEggertson is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jan 2002
Location: Seattle WA
Posts: 863 MJEggertson User rank is Corporal (100 - 500 Reputation Level)MJEggertson User rank is Corporal (100 - 500 Reputation Level)MJEggertson User rank is Corporal (100 - 500 Reputation Level)MJEggertson User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 22 sec
Reputation Power: 8
Heh, you must've clicked the reply button before I edited my post.

Thanks for you patience though.

-Mike

Reply With Quote
  #6  
Old February 20th, 2002, 06:50 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Dev Shed God 5th Plane (7000 - 7499 posts)
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,335 Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level)Scorpions4ever User rank is Brigadier General (60000 - 70000 Reputation Level) 
Time spent in forums: 4 Weeks 12 h 27 m 15 sec
Reputation Power: 662
No problemo, I'm always glad to help. Besides, answering questions helps me become a better programmer as well .
You're right about the reply button --- I was replying while you were editing your post.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > [C++] try, catch, throw and destructors


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

 Free IT White Papers!
 
Accelerating Trading Partner Performance
One in five. That's how many partner transactions have at least one error. That is an amazing statistic, particularly given the extraordinary leaps in innovation across the global supply chain during the past two decades. Download this white paper to learn more.

 
Competing on Analytics
This Tech Analysis is designed to help identify characteristics shared by analytics competitors, and includes information about 32 organizations that have made a commitment to quantitative, fact-based analysis.

 
Cost Effective Scaling with Virtualization and Coyote Point Systems
An overview of the industry trend toward virtualization, how server consolidation has increased the importance of application uptime and the steps being taken to integrate load balancing technology with virtualized servers.

 
Five Checkpoints to Implementing IP Telephony
Implementation planning for IP PBX software and IP telephony has become vital as businesses replace discontinued legacy PBX phone systems. This informative whitepaper outlines five "checkpoints" for any implementation plan that will help make IP communications a successful proposition.

 
Hosted Email Security: Staying Ahead of New Threats
In the last two years, email has become a fierce battleground between the nefarious forces of spam and malware, and the heroes of messaging protection. The spam volumes increased alarmingly every month, bringing clever new forms of phishing and virus propagation attacks.

 

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 2 hosted by Hostway