Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > A simple validity check. But need your kind help!

Reply
Thread Tools

A simple validity check. But need your kind help!

 
 
shuisheng
Guest
Posts: n/a
 
      02-16-2007
Dear All,

Assume I have a class for a cuboid domain. The domain is defined by
the cuboid's lower corner, such as (0, 0, 0), and upper corner, such
as (1, 1, 1). The upper corner should be always higher than the lower
corner. I write a code as below

class Domain
{
private:
double mLowerCorner[3];
double mUpperCorner[3];

public:
double* GetLowerCorner() {return mLowerCorner;}
double* GetUpperCorner() {return mUpperCorner;}

void SetLowerCorner(double lowerCorner[3])
{
if (mUpperCorner[0] < lowerCorner[0] || // Validity check
mUpperCorner[1] < lowerCorner[1] ||
mUpperCorner[2] < lowerCorner[2] )
{
throw out_of_range("Error");
}
mLowerCorner[0] = lowerCorner[0];
mLowerCorner[1] = lowerCorner[1];
mLowerCorner[2] = lowerCorner[2];
}

// My question is here: I need similar functions
// void SetUpperCorner(double upperCorner[3]),
// void SetDomain(double lowerCorner[3], double upperCorner[3]),
// and constructors.
// and so on. The check make me very uncomfortable.
};

Anyone can give me a good suggestion to solve the problem?

Thanks a lot!

Shuisheng

 
Reply With Quote
 
 
 
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      02-16-2007
shuisheng wrote:

> Dear All,
>
> Assume I have a class for a cuboid domain. The domain is defined by
> the cuboid's lower corner, such as (0, 0, 0), and upper corner, such
> as (1, 1, 1). The upper corner should be always higher than the lower
> corner. I write a code as below
>
> class Domain
> {
> private:
> double mLowerCorner[3];
> double mUpperCorner[3];
>
> public:
> double* GetLowerCorner() {return mLowerCorner;}
> double* GetUpperCorner() {return mUpperCorner;}


These methods expose the arrays. Client code could say:

(GetLowerCorner())[1] = 2.0;

and change the entries. In that case, the client will bypass all validity
checks whatsoever. At least, you need:

double const * GetLowerCorner() const {return mLowerCorner;}
double const * GetUpperCorner() const {return mUpperCorner;}

> void SetLowerCorner(double lowerCorner[3])
> {
> if (mUpperCorner[0] < lowerCorner[0] || // Validity check
> mUpperCorner[1] < lowerCorner[1] ||
> mUpperCorner[2] < lowerCorner[2] )
> {
> throw out_of_range("Error");
> }
> mLowerCorner[0] = lowerCorner[0];
> mLowerCorner[1] = lowerCorner[1];
> mLowerCorner[2] = lowerCorner[2];
> }
>
> // My question is here: I need similar functions
> // void SetUpperCorner(double upperCorner[3]),
> // void SetDomain(double lowerCorner[3], double upperCorner[3]),
> // and constructors.
> // and so on. The check make me very uncomfortable.
> };


What should make you uncomfortable is not the checks but the sheer
complexity you are inviting just to deal with two points in space.

What about making domains immutable and putting a little more intelligence
into the points:

#include <tr1/array>
#include <stdexcept>

// warning: [bad hack, there is no guarantee that we can derive from array]
/*
(a) We use derivation rather than a typedef so that operator- only applies
to this type.
(b) Some people will prefer to derive privately and import all methods via
using directives.
*/
struct vector3d : public std::tr1::array<double,3> {

vector3d ( double x = 0.0,
double y = 0.0,
double z = 0.0 )
{
(*this)[0] = x;
(*this)[1] = y;
(*this)[2] = z;
}

};

vector3d operator- ( vector3d const & lhs, vector3d const & rhs ) {
vector3d result;
for ( unsigned i = 0; i < 3; ++i ) {
result[i] = lhs[i] - rhs[i];
}
return ( result );
}


bool is_strictly_positive ( vector3d const & v ) {
for ( unsigned i = 0; i < 3; ++i ) {
if ( v[i] <= 0 ) {
return ( false );
}
}
return ( true );
}

bool does_define_box ( vector3d const & bot,
vector3d const & top ) {
return ( is_strictly_positive( top - bot ) );
}

class immutableDomain {

vector3d bot;
vector3d top;

public:

immutableDomain ( vector3d const & b, vector3d t )
: bot(b)
, top(t)
{
if ( ! does_define_box( bot, top ) ) {
throw std:ut_of_range( "Error" );
}
}

vector3d const & lowerCorner ( void ) const {
return ( bot );
}

vector3d const & upperCorner ( void ) const {
return ( top );
}

};

If you want to, you can define a mutable Domain class wrapping around the
immutable one:

class Domain {

immutableDomain the_data;

public:

Domain ( vector3d const & b, vector3d const & t )
: the_data( b, t )
{}

vector3d const & getLowerCorner ( void ) const {
return ( the_data.lowerCorner() );
}

vector3d const & getUpperCorner ( void ) const {
return ( the_data.upperCorner() );
}

void setLowerCorner ( vector3d const & bot ) {
the_data = immutableDomain( bot, the_data.upperCorner() );
}

void setUpperCorner ( vector3d const & top ) {
the_data = immutableDomain( the_data.lowerCorner(), top );
}

};

The constructor of immutableDomain will be the only place where the
invariant is checked.


Best

Kai-Uwe Bux
 
Reply With Quote
 
 
 
 
Jerry Coffin
Guest
Posts: n/a
 
      02-16-2007
In article <(E-Mail Removed) .com>,
http://www.velocityreviews.com/forums/(E-Mail Removed) says...
> Dear All,
>
> Assume I have a class for a cuboid domain. The domain is defined by
> the cuboid's lower corner, such as (0, 0, 0), and upper corner, such
> as (1, 1, 1). The upper corner should be always higher than the lower
> corner. I write a code as below


I'd add private functions to check the condition, and do the assignment.
Using this, the rest become pretty trivial:

class Domain {
double mLowerCorner[3];
double mUpperCorner[3];

bool check(double *lower, double *upper) {
if (upper[0] < lower[0] ||
upper[1] < lower[1] ||
upper[2] < lower[2])
throw out_of_range("Error");
}

void assign(double &a, double const &b) {
a[0] = b[0];
a[1] = b[1];
a[2] = b[2];
}

public:
void SetLowerCorner(double lower[3]) {
check(lower, mUpperCorner);
assign(mLowerCorner, lower);
}

void SetUpperCorner(double upper[3]) {
check(mLowerCorner, upper);
assign(mUpperCorner, upper);
}

void SetDomain(double *lower, double *upper) {
check(lower, upper);
assign(mLowerCorner, lower);
assign(mUpperCorner, upper);
}

Domain(double *lower, double *upper) {
SetDomain(lower, upper);
}
// ...
};

--
Later,
Jerry.

The universe is a figment of its own imagination.
 
Reply With Quote
 
 
 
Reply

Thread Tools

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

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to call a simple perl script from HTML without need of HTTPS but simple HTTP ? Wladimir Borsov Perl Misc 4 05-11-2006 09:29 AM
BGP vs OSPF routes validity matteo_cardelli@yahoo.co.uk Cisco 3 05-12-2005 06:53 AM
Search a keyword but but only on one kind of tag Marc Pichouron Javascript 0 01-08-2004 08:40 AM
Validity of MCSD .NET Kamal Ahmed MCSD 2 10-04-2003 08:52 AM
MIKE Your my saviour...but i still need your help...:S suntzu Computer Support 7 08-05-2003 03:23 AM



Advertisments