473,659 Members | 2,671 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

how to make a simple class that is either an int or a float

Ben
Hi all,

I'm not yet good at thinking the right way in c++ so although I could
solve this problem, I'm not sure if they way I'm thinking of is the best
way to do it. I need a data type or class or something that can hold
either an int, or a float, knows which one it is holding, and will allow
me to do comparisons with instances of it without the code which asks
for the comparison having to know which one it is. So maybe I could do
it something like this (haven't compiled it so there are probably little
errors but hopefully you get the gist):

class Int_or_float {
int i;
float f;
bool is_int;
public:
bool Int_or_float::o perator==( Int_or_float &a ) {
if( this->is_int ) return this->i == a.i;
else return this->f == a.f;
}
}

I could do it more simply perhaps like this:

class Int_or_float {
public:
int i;
float f;
bool is_int;
}

bool equal( Int_or_float x, y ) {
if( x.is_int ) return x.i == y.i;
else return x.f == y.f;
}

I realise neither of these will behave well if you compare one storing
an int with one storing a float.

So what are the pros and cons of each method? Is there an even simpler
method? I hoped I might be able to use a union but I can't think how. I
suppose if I want to use the STL I have no choice but to use the first
way?

Thanks in advance,

Ben

Jul 22 '05 #1
7 1860
"Ben" <be************ **@zoology.ox.a c.uk> wrote in message
I'm not yet good at thinking the right way in c++ so although I could
solve this problem, I'm not sure if they way I'm thinking of is the best
way to do it. I need a data type or class or something that can hold
either an int, or a float, knows which one it is holding, and will allow
me to do comparisons with instances of it without the code which asks
for the comparison having to know which one it is. So maybe I could do
it something like this (haven't compiled it so there are probably little
errors but hopefully you get the gist):

class Int_or_float {
int i;
float f;
bool is_int;
public:
bool Int_or_float::o perator==( Int_or_float &a ) {
if( this->is_int ) return this->i == a.i;
else return this->f == a.f;
}
}

I could do it more simply perhaps like this:

class Int_or_float {
public:
int i;
float f;
bool is_int;
}

bool equal( Int_or_float x, y ) {
if( x.is_int ) return x.i == y.i;
else return x.f == y.f;
}

I realise neither of these will behave well if you compare one storing
an int with one storing a float.

So what are the pros and cons of each method? Is there an even simpler
method? I hoped I might be able to use a union but I can't think how. I
suppose if I want to use the STL I have no choice but to use the first
way?

Thanks in advance,


This is actually a complicated problem. The first way is preferred as it
using private variables and encapsulation. But instead of a flag indicating
the type of an object, one should prefer to use virtual functions. The
standard solution is something like:

class Variable {
public:
virtual ~Variable() = 0;
virtual std::auto_ptr<V ariable> clone() const = 0;
};

class Int : public Variable {
public:
Int(int data);
std::auto_ptr<V ariable> clone() const;
private:
int d_data;
};

To handle comparing arbitrary types, one can use double dispatch. This is
when a (non-member usually) function is virtual in both its arguments. C++
does not provide native support for this, but you can build it yourself.
Look it up in the books or the internet. Here are the basics:

First, provide 4 operator== functinos, to compare Int to Int, Int to Double,
etc.

Basically you create a 2 by 2 matrix, or map, or whatever.

m["Int"]["Int"] maps to the function compare an Int to Int.
m["Int"]["Double"] maps to the function compare an Int to Double.

When the user calls operator==(vari able1, variable2), look up the
appropriate function to call in the matrix map, then call it. If no
function found you throw an exception, or choose your favorite error
handling routine.

The advantage of this approach is that you can add new types, and all you
need is to derive a new class and provide the new equal functions, and store
these in the matrix.

But in your case you might not need double dispatch. Instead you could
provide a function asFloat() in the base variable class.

class Variable {
public:
virtual ~Variable() = 0;
virtual std::auto_ptr<V ariable> clone() const = 0;
virtual double asDouble() const = 0;
};

inline
bool operator==(cons t Variable& lhs, const Variable&) {
return lhs.asDouble() == rhs.asDouble();
}
Jul 22 '05 #2
In article <1b************ ******@bgtnsc04-news.ops.worldn et.att.net>,
Siemel Naran <Si*********@RE MOVE.att.net> wrote:
To handle comparing arbitrary types, one can use double dispatch. This is
when a (non-member usually) function is virtual in both its arguments. C++
does not provide native support for this, but you can build it yourself.
Look it up in the books or the internet. Here are the basics:

First, provide 4 operator== functinos, to compare Int to Int, Int to Double,
etc.

Basically you create a 2 by 2 matrix, or map, or whatever.

m["Int"]["Int"] maps to the function compare an Int to Int.
m["Int"]["Double"] maps to the function compare an Int to Double.

When the user calls operator==(vari able1, variable2), look up the
appropriate function to call in the matrix map, then call it. If no
function found you throw an exception, or choose your favorite error
handling routine.

The advantage of this approach is that you can add new types, and all you
need is to derive a new class and provide the new equal functions, and store
these in the matrix.


There's an easier way to do double dispatch (especially for small sets
of possible types) that avoids having to explicitly determine the type
of objects by having a general method invoked on one class invoke a more
specific method in the other:

--------
class Value
{
public:
/*Return greater than, less than, or equal to 0 depending on whether
other's value is greater than, less than, or equal to ours
*/
virtual int compare(const Value& other) const =0;
protected:
virtual int compareWithInt( int other) const =0;
virtual int compareWithDoub le(double other) const =0;
};

class IntValue
{
private:
int myInt;
public:
IntValue(int i):myInt(i) {}
virtual int compare(const Value& other) const
{return -other.compareWi thInt(myInt);}
protected:
virtual int compareWithInt( int other) const
{return other<myInt?-1:(myInt==other ?0:1);}
virtual int compareWithDoub le(double other) const
{return other<myInt?-1:(myInt==other ?0:1);}
};

class DoubleValue
{
private:
double myDouble;
public:
DoubleValue(int i):myDouble(i) {}
virtual int compare(const Value& other) const
{return -other.compareWi thDouble(myDoub le);}
protected:
virtual int compareWithInt( int other) const
{return other<myDouble?-1:(myDouble==ot her?0:1);}
virtual int compareWithDoub le(double other) const
{return other<myDouble?-1:(myDouble==ot her?0:1);}
};

--------

(But for your specific problem, the idea upthread of just implementing
asDouble and calling that in the comparison is probably better than
using double dispatch.)
dave

--
Dave Vandervies dj******@csclub .uwaterloo.ca
Disagreeable intelligent folk make my day.
Of course, I'm biased.
--Brenda
Jul 22 '05 #3
Ben wrote:

Hi all,

I'm not yet good at thinking the right way in c++ so although I could
solve this problem, I'm not sure if they way I'm thinking of is the best
way to do it. I need a data type or class or something that can hold
either an int, or a float, knows which one it is holding, and will allow
me to do comparisons with instances of it without the code which asks
for the comparison having to know which one it is. So maybe I could do
it something like this (haven't compiled it so there are probably little
errors but hopefully you get the gist):

class Int_or_float {
int i;
float f;
bool is_int;
public:
bool Int_or_float::o perator==( Int_or_float &a ) {
if( this->is_int ) return this->i == a.i;
else return this->f == a.f;
}
}

I could do it more simply perhaps like this:

class Int_or_float {
public:
int i;
float f;
bool is_int;
}

bool equal( Int_or_float x, y ) {
if( x.is_int ) return x.i == y.i;
else return x.f == y.f;
}

I realise neither of these will behave well if you compare one storing
an int with one storing a float.

So what are the pros and cons of each method? Is there an even simpler
method? I hoped I might be able to use a union but I can't think how. I
suppose if I want to use the STL I have no choice but to use the first
way?


If you want a minimalistic class and lightweight objects,
here is one sketch:

class Value {
enum Type {
type_int,
type_flt
};

union {
int v_int_;
float v_flt_;
};
int type_;

bool cmp_equal_type( Value const& rhs) const {
bool ret;
switch(type_) {
case type_int:
ret = v_int_ == rhs.v_int_;
break;
case type_flt:
ret = v_flt_ == rhs.v_flt_;
break;
default:
ret = false;//assert() or remove the option
}
return ret;
}

typedef double promote_t; //system-dependent

promote_t get_promoted() const {
promote_t ret;
switch(type_) {
case type_int:
ret = v_int_;
break;
case type_flt:
ret = v_flt_;
break;
default:
ret = 0;//assert() or remove the option
}
return ret;
}

public:
Value(int v) : v_int_(v), type_(type_int) {}
Value(float v) : v_flt_(v), type_(type_flt) {}

bool operator ==(Value const& rhs) const {
return rhs.type_ == type_? cmp_equal_type( rhs) :
(get_promoted() == rhs.get_promote d());
}

//...
};
Denis
Jul 22 '05 #4
Denis Remezov posted:
class Value {
enum Type {
type_int,
type_flt
};

union {
int v_int_;
float v_flt_;
};

What's the story with that? You haven't declared any variables/objects.

-JKop
Jul 22 '05 #5
Ben
Thanks very much for your suggestions folks...

I can just about get my head round the second suggestion. The first
suggestions is making me realise I have plenty more to learn - so I'll try!

Cheers,

Ben
Jul 22 '05 #6

"JKop" <NU**@NULL.NULL > wrote in message
news:q7******** *********@news. indigo.ie...
Denis Remezov posted:
class Value {
enum Type {
type_int,
type_flt
};

union {
int v_int_;
float v_flt_;
};

What's the story with that? You haven't declared any variables/objects.

-JKop


It's called an anonymous union, v_int_ and v_flt_ are member variables of
class Value.

john
Jul 22 '05 #7
"Dave Vandervies" <dj******@csclu b.uwaterloo.ca> wrote in message
news:cafu2h$nr6
Siemel Naran <Si*********@RE MOVE.att.net> wrote:
To handle comparing arbitrary types, one can use double dispatch. This iswhen a (non-member usually) function is virtual in both its arguments. C++does not provide native support for this, but you can build it yourself.
Look it up in the books or the internet. Here are the basics:

First, provide 4 operator== functinos, to compare Int to Int, Int to Double,etc.

Basically you create a 2 by 2 matrix, or map, or whatever.

m["Int"]["Int"] maps to the function compare an Int to Int.
m["Int"]["Double"] maps to the function compare an Int to Double.

When the user calls operator==(vari able1, variable2), look up the
appropriate function to call in the matrix map, then call it. If no
function found you throw an exception, or choose your favorite error
handling routine.

The advantage of this approach is that you can add new types, and all you
need is to derive a new class and provide the new equal functions, and storethese in the matrix.


There's an easier way to do double dispatch (especially for small sets
of possible types) that avoids having to explicitly determine the type
of objects by having a general method invoked on one class invoke a more
specific method in the other:

--------
class Value
{
public:
/*Return greater than, less than, or equal to 0 depending on whether
other's value is greater than, less than, or equal to ours
*/
virtual int compare(const Value& other) const =0;
protected:
virtual int compareWithInt( int other) const =0;
virtual int compareWithDoub le(double other) const =0;
};


But this approach still suffers the disadvantage of not being as extensible.
Suppose you want to add a new type like Complex or String. With my proposed
code you just add your classes, new comparison functions, register these in
the double dispatch registry. With your approach we have to change the base
class to add new functions compareWithComp lex and compareWithStri ng.
(But for your specific problem, the idea upthread of just implementing
asDouble and calling that in the comparison is probably better than
using double dispatch.)


Right, in certain special cases we don't need the full blown double
dispatch.

Though who knows. There's a case for a special function here. Maybe to
compare two doubles we want to compare for approximatley equal, because two
doubles calculated through different formula may be slightly different
thanks to imperfect floating point math, example (1.0) and (1.0/3)*3.0 are
really both 1 but may be 1.0 and 0.9999* because of floating point math.
Jul 22 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
8658
by: Randi | last post by:
Hi, Looking for some help with this payrool project I have for class. This is what the instructor asks for so far. I have it working without errors but am getting some funky numbers. I am not sure if they would be correct anyways. Below is the instructions. and below that is what I have. Any tips or hints would be highly appreciated. Regards, Kelsey
12
3290
by: Steven T. Hatton | last post by:
This is something I've been looking at because it is central to a currently broken part of the KDevelop new application wizard. I'm not complaining about it being broken, It's a CVS images. Such things happen. The whole subsystem is going through radical changes. I don't really want to say what I think of the code just yet. That would influence the opinions of others, and I really want to know how other people view these things,...
8
1452
by: Lou Pecora | last post by:
Problem: If I inherit an object B from A and use references in B to data in A, arrays of B objects which are pointed to by an A pointer causes "EXC_BAD_ACCESS" errors at the point shown in the code below. Removing the references cures the problem. Throughout, the correct virtural functions are called. The code is dirt simple (below). Can anyone explain why reference in the interited object ruin the array structure in some way that...
4
1463
by: hufel | last post by:
Hi, I'm doing my first big project in C# and I'm stuck with a problem that I believe has a simple and efficient solution for it (I just haven't bumped into it yet...). The concept is the following: //Users manage clients. When the system creates the client it must fetch the information from the DB and allow some modifications: Client client = new Client("test"); MasterAccount ma = new MasterAccount(1324651);
24
6320
by: firstcustomer | last post by:
Hi, Firstly, I know NOTHING about Javascript I'm afraid, so I'm hoping that someone will be able to point me to a ready-made solution to my problem! A friend of mine (honest!) is wanting to have on his site, a Javascript Calculator for working out the cost of what they want, for example: 1 widget and 2 widglets = £5.00
7
3456
by: mathieu | last post by:
Hello, I did read the FAQ on template(*), since I could not find an answer to my current issue I am posting here. I have tried to summarize my issue in the following code (**). Basically I am trying to hide the `complexity` of template from the user interface. If you look at the code DataSet should be the object that my user manipulate. Unfortunately by doing so the object returned by DataSet::Get is a FloatingPt, so without the virtual...
5
313
by: frankb.mail | last post by:
Ok i'm new to C++ and am teaching myself i've hit a small block that I can't seem to get around I am trying to convert an array like std::string load; into a float array. The code looks like this: float flaod;
1
1708
by: Bl00dFox | last post by:
Hi I am making a simple program to calculate interest. At the beginning when the user has to pick 1 or 2 (to select simple or compound interest respectively), if the user enters a letter (eg, a) the program goes haywire (the main repeats over and over again). Is there a way to limit the user in entering only numbers, not letters or characters? Here is the code: // Interest calculator, by Bl00dFox #include <iostream>
0
1656
by: Andreas Schmitt | last post by:
I wrote a small timer class for use in a graphics engine I am working on for teaching myself. The small time based animations I tried with it seem to work fine but displaying the frame rate I noticed a certain "drop in framerate" to appear at regular intervals without any apparent reason. Here's the code I'm using: class BasicTimer
0
8427
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8332
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8746
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8525
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
5649
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4175
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4335
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2750
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1737
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.