using exceptions to stop object creation

Z

Zork

Hi,

I am trying to stop object creation (in this case ill use a ball as the
object) via use of exceptions. In essence, if the ball does not have an
owner, I do not want the ball object created. Here is my program sketch:

-------------------------
#include <sstream>

class NullOwnerException : public exception
{
public:
NullOwnerException::NullOwnerException() : exception ( "A NULL owner was
found" ) {}
};

// Ball constructor
Ball :: Ball ( Owner * o, string c, double r )
{
if ( ! o ) throw NullOwnerException(); // the ball does not have an owner

Owner = o;
Color = c;
Radius = r;
}
..
..
int main ( void )
{
Owner o1 = Owner("John");
Ball b1;

try { b1 = Ball(&o1, "Blue", 10.3); }
catch ( NullOwnerException & nullOwnerException )
{cout << nullOwnerException.what() << endl ; }
}
----------------------

Now the above works fine, but the question is, is there any way of hiding
the try{}catch(){} from the main(void) ? I was hoping of just having a clean
main as follows:

int main ( void )
{
Owner o1 = Owner("John");
Ball b1= Ball(&o1, "Blue", 10.3);
}

Maybe the constructor itself can handle the exception? I do not want to use
a factory method.

Thanks for any help!

Zork
 
B

Buster

Zork said:
Hi,

I am trying to stop object creation (in this case ill use a ball as the
object) via use of exceptions. In essence, if the ball does not have an
owner, I do not want the ball object created. Here is my program sketch:

int main ( void )
{
Owner o1 = Owner("John");

By the way...
Conceptually, the above line initializes a temporary Owner object using
a constructor that accepts a string, then copies that object into the
auto o1 variable using the copy constructor. It is simpler to initialize
o1 straight from a string, as:

Owner o1 ("John");

The same applies to the line below, of course.
Ball b1= Ball(&o1, "Blue", 10.3);
(*)

}

Maybe the constructor itself can handle the exception?

Handle it how? A constructor either (i): constructs an object; or
(ii): throws an exception; there is no (iii).
I do not want to use a factory method.

OK.

At the point in your program I marked with a (*), you can use "b1"
to refer to a Ball object. The object exists, i.e., one of its
constructors has successfully completed. You cannot get to (*)
otherwise, and you don't want to. If the constructor failed (threw an
exception) the flow has to pass to some other part of the program.
try/catch is just the mechanism for specifying what part. There is no
alternative mechanism. (There's std::set_terminate, but don't use that
for this.)
 
R

Rolf Magnus

Zork said:
Hi,

I am trying to stop object creation (in this case ill use a ball as
the object) via use of exceptions. In essence, if the ball does not
have an owner, I do not want the ball object created.

If you don't want to allow null pointer, why don't you use a reference
instead?
Here is my
program sketch:

-------------------------
#include <sstream>

class NullOwnerException : public exception
{
public:
NullOwnerException::NullOwnerException() : exception ( "A NULL owner
was found" ) {}
};

// Ball constructor
Ball :: Ball ( Owner * o, string c, double r )
{
if ( ! o ) throw NullOwnerException(); // the ball does not have an
owner

Owner = o;
Color = c;
Radius = r;
}
.
.
int main ( void )
{
Owner o1 = Owner("John");
Ball b1;

So your Ball has a default constructor? If not, that shouldn't compile.
If yes, you already created a ball without an owner here. You have to
create your Ball within the try block and you must not have a default
constructor for Ball.
try { b1 = Ball(&o1, "Blue", 10.3); }
catch ( NullOwnerException & nullOwnerException )
{cout << nullOwnerException.what() << endl ; }
}
----------------------

int main ( void )
{
Owner o1 = Owner("John");

try
{
Ball b1(&o1, "Blue", 10.3);
//do whatever you want with the ball
}
catch ( const NullOwnerException & nullOwnerException )
{
cout << nullOwnerException.what() << endl ;
}
}
Now the above works fine, but the question is, is there any way of
hiding the try{}catch(){} from the main(void) ? I was hoping of just
having a clean main as follows:

int main ( void )
{
Owner o1 = Owner("John");
Ball b1= Ball(&o1, "Blue", 10.3);
}

Why? If you want to handle an exception, you have to write the code to
do so.
Maybe the constructor itself can handle the exception?

You are generating the execption in the constructor. If it could handle
it on its own, you wouldn't need an exception in the first place. You
use exceptions if you get a condition that you cannot handle at the
place where it occurs.
 
B

Buster

Zork wrote:

[...]
int main ( void )
{
Owner o1 = Owner("John");
Ball b1;

try { b1 = Ball(&o1, "Blue", 10.3); }
catch ( NullOwnerException & nullOwnerException )
{cout << nullOwnerException.what() << endl ; }
}

[...]

I missed this when I wrote my other reply. In that other language, the
line "Ball b1;" declares a variable of type reference-to-Ball. Then you
use "b1 = new Ball (...)" to bind the reference to an object. In C++,
that kind of reference is called a pointer and you use something like:

Ball * b1;
b1 = new Ball (...);

The reason you don't want to do this all the time in C++ is because the
object won't automatically be destroyed when the pointer's name goes out
of scope (only the pointer is destroyed). Instead, you do it like this:

Ball b (...);

This declares a variable of type Ball. The entire object is kept in the
same place where just a reference would be kept in the other language.
(Accordingly the object is destroyed when its name goes out of scope.)
This is one of the reasons C++ is fast - there's usually one layer of
indirection fewer. It only works when the object has a fixed size known
in advance, which is one of the reasons we sometimes need to ask for a
reference or pointer instead and keep the real object somewhere else.

Similarly, in C++ the delaration "Ball b;" gets you a real object, not
just a reference. An object doesn't exist until one of its constructors
has successfully returned. In this case the default constructor is used.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,164
Messages
2,570,898
Members
47,440
Latest member
YoungBorel

Latest Threads

Top