473,466 Members | 1,307 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Is this good OOP?

Is this a good way of making use of OOP? Also, is this a good way of
computing Fibonacci numbers?

Code:

#include <iostream>
#include <cstdlib>
using namespace std;

template <class T>
class invalidArg
{
public:
virtual void Write(T& arg)const{cout << arg << " is invalid. " <<
endl;}
};

class fib
{
public:
unsigned long operator()(unsigned long n)
{
if(n<=0)
throw invalidArg<unsigned long>();
else if(n==1||n==2)
return 1;
unsigned long a=1, b=0;
unsigned long i=0x8000;
while (i)
{
unsigned long aa;
aa=n&i?(2*b+a)*a:a*a+b*b;
b=n&i?a*a+b*b:b*(2*a-b);
a=aa;
i>>=1;
}
return b;
}
};

class mainObj
{
public:
static mainObj* Instance()
{
if(!instanceFlag)
{
main=new mainObj();
instanceFlag=true;
return main;
}
else
return main;
}
~mainObj()
{
instanceFlag=false;
}
private:
mainObj()
{
for(;;)
{
cout << "Enter a number: " << endl;
unsigned long x;
cin >> x;
try
{
cout << "Value of fibonacci number: " << fib()(x) << endl;
}
catch(invalidArg<unsigned long>& inv)
{
inv.Write(x);
}
catch(...)
{
cout << "An error has occurred. Please contact Microsoft for
assistance. "
<< endl;
}
}
}
static bool instanceFlag;
static mainObj *main;
};
bool mainObj::instanceFlag = false;
mainObj* mainObj::main=0;
namespace{mainObj* Main=mainObj::Instance();}
int main(){system("PAUSE"); return 0;}

Is this good OOP? Thanks.

Nov 5 '05 #1
16 1738

"Protoman" <Pr**********@gmail.com> wrote in message
news:11*********************@g49g2000cwa.googlegro ups.com...
Is this a good way of making use of OOP? Also, is this a good way of
computing Fibonacci numbers?

Code:

#include <iostream>
#include <cstdlib>
using namespace std;

template <class T>
class invalidArg
{
public:
virtual void Write(T& arg)const{cout << arg << " is invalid. " <<
endl;}
};

class fib
{
public:
unsigned long operator()(unsigned long n)
{
if(n<=0)
throw invalidArg<unsigned long>();
else if(n==1||n==2)
return 1;
unsigned long a=1, b=0;
unsigned long i=0x8000;
while (i)
{
unsigned long aa;
aa=n&i?(2*b+a)*a:a*a+b*b;
b=n&i?a*a+b*b:b*(2*a-b);
a=aa;
i>>=1;
}
return b;
}
};

class mainObj
{
public:
static mainObj* Instance()
{
if(!instanceFlag)
{
main=new mainObj();
instanceFlag=true;
return main;
}
else
return main;
}
~mainObj()
{
instanceFlag=false;
}
private:
mainObj()
{
for(;;)
{
cout << "Enter a number: " << endl;
unsigned long x;
cin >> x;
try
{
cout << "Value of fibonacci number: " << fib()(x) << endl;
}
catch(invalidArg<unsigned long>& inv)
{
inv.Write(x);
}
catch(...)
{
cout << "An error has occurred. Please contact Microsoft for
assistance. "
<< endl;
}
}
}
static bool instanceFlag;
static mainObj *main;
};
bool mainObj::instanceFlag = false;
mainObj* mainObj::main=0;
namespace{mainObj* Main=mainObj::Instance();}
int main(){system("PAUSE"); return 0;}

Is this good OOP? Thanks.


No, sorry I don't see any OOP at all in this example, its just uses a lot of
various unnecessary C++ features. You could have done the whole thing much
simpler as a simple Fibonacci number generator function.

Perhaps you could consider a Fibonacci object which would generate Fibonacci
numbers efficinetly
by caching the intermediate numbers when calculating a new value. In that
case this would have some
OOP, the object would have some internal state.

dave

Nov 5 '05 #2
What do you mean? It uses classes and stuff.

Nov 5 '05 #3

Protoman wrote:
Is this a good way of making use of OOP? Also, is this a good way of
computing Fibonacci numbers?

Code:

#include <iostream>
#include <cstdlib>
using namespace std;

template <class T>
class invalidArg
{
public:
virtual void Write(T& arg)const{cout << arg << " is invalid. " <<
endl;}
};

class fib
{
public:
unsigned long operator()(unsigned long n)
{
if(n<=0)
throw invalidArg<unsigned long>();
else if(n==1||n==2)
return 1;
unsigned long a=1, b=0;
unsigned long i=0x8000;
while (i)
{
unsigned long aa;
aa=n&i?(2*b+a)*a:a*a+b*b;
b=n&i?a*a+b*b:b*(2*a-b);
a=aa;
i>>=1;
}
return b;
}
};

class mainObj
{
public:
static mainObj* Instance()
{
if(!instanceFlag)
{
main=new mainObj();
instanceFlag=true;
return main;
}
else
return main;
}
~mainObj()
{
instanceFlag=false;
}
private:
mainObj()
{
for(;;)
{
cout << "Enter a number: " << endl;
unsigned long x;
cin >> x;
try
{
cout << "Value of fibonacci number: " << fib()(x) << endl;
}
catch(invalidArg<unsigned long>& inv)
{
inv.Write(x);
}
catch(...)
{
cout << "An error has occurred. Please contact Microsoft for
assistance. "
<< endl;
}
}
}
static bool instanceFlag;
static mainObj *main;
};
bool mainObj::instanceFlag = false;
mainObj* mainObj::main=0;
namespace{mainObj* Main=mainObj::Instance();}
int main(){system("PAUSE"); return 0;}

Is this good OOP? Thanks.


Well, I think you got a bit carried away with the object-oriented
programming. Not everything is improved by turning it into an object.
For instance, the function "main" does not really lend itself to an
object-oriented model. Therefore MainObj (and, by the way, let's buy a
vowel and ask Vanna for some consonants so that we can use complete
words as names: MainObject instead of MainObj, for example). (And one
other tip along those lines: there is a "tab" key on your keyboard.)

There are two problems with MainObj: the first is that practically the
entire program executes within MainObj's constructor. First, no one is
going to know to look there to find the program. Everyone will look
first at main(). Otherwise, there is no convention of having a
"MainObj" with which other programmers will be familiar. Imagine if
this program had 50 classes and 50 source files, who would want to look
through them all wondering where the main routine really is.

The other problem is that executing the program before main() means
that global objects in other files may not yet be initialized when
MainObj's constructor is called; subtle bugs can occur as a result. In
short, "main" exists for a reason - it is the first function executed
after everything has been set up, and a function with which every C and
C++ programmer will look for. A program should take advantage of both
of those facts.

Greg

Nov 5 '05 #4
OK then, how's my fib() funct? Is it efficient?

Nov 5 '05 #5
Protoman wrote:
What do you mean? It uses classes and stuff.


Exactly, it uses classes where they are totally unnecessary. Here's a
tip, if you write a class that has no data members at all you should
consider whether you need to make that a class at all.

Here one valid possibility for OOP fibonacci numbers. Classes like the
following are called generators.

class FibGenerator
{
public:
FibGenerator() : a(0), b(1) {}
int operator()
{
int res = a + b;
a = b;
b = res;
return res;
}
private:
int a;
int b;
};

int main()
{
FibGenerator fib;
for (int i = 0; i < 10; ++i)
cout << fib() << '\n';
}

Untested code.

john
Nov 5 '05 #6
>
Here one valid possibility for OOP fibonacci numbers. Classes like the
following are called generators.


And here's a version that actually works.

#include <iostream>
using namespace std;

class FibGenerator
{
public:
FibGenerator() : a(0), b(1) {}
int operator()()
{
int next = a + b;
a = b;
b = next;
return a;
}
private:
int a;
int b;
};

int main()
{
FibGenerator fib;
for (int i = 0; i < 10; ++i)
cout << fib() << '\n';
}
Nov 5 '05 #7

"Protoman" <Pr**********@gmail.com> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
What do you mean? It uses classes and stuff.


You code is neither good or OOP just because it uses classes and stuff.
You've used a
number of advanced C++ language features very ineffectively:

1. Your fibonacci class has no data which supports the computation of
Fibonacci
numbers, so you might as well use a simple free function for that.
Usually objects
have their own state and identity otherwise they aren't very interesting
or useful

2. You have introduced an invalidArg class template although only one type
is used in
the program. The invalidArg class also writes to cout which makes the
class less useful
and reuseable. ( eg, if I write a windows GUI app, writing to cout is
not a useful thing to do, or
what if I want to write to stderr ? ). Throw the exception by all
means, but let the client deal with the exception himself. Put the
information about the exception into the exception class and let your client
deal with it.

3. Only one exception can be thrown from your fibonacci generator, so
perhaps that should be
specified in the signature. You've put in a catch(...) which is
desperation, you should check carefully
that your fibonacci calculation can never throw exceptions and then
remove the catch(...).

You've not done anything to guard against arithmetic overflow when the
Fibonacci number is too
big to be stored in a long.

4. The mainObj serves no useful purpose and just adds a lot of complexity
over the simple main()
function.

Here's my improved version with some of the suggestions.....

#include <iostream>
#include <cstdlib>
using namespace std;

template <class T>
class invalidArg
{
public:
virtual void Write(T& arg)const{cout << arg << " is invalid. " << endl;}
};
unsigned long Fibonacci( unsigned long n)
{
if(n<=0)
throw invalidArg<unsigned long>();
else if(n==1||n==2)
return 1;

unsigned long a=1, b=0;
unsigned long i=0x8000;
while (i)
{
unsigned long aa;
aa=n&i?(2*b+a)*a:a*a+b*b;
b=n&i?a*a+b*b:b*(2*a-b);
a=aa;
i>>=1;
}
return b;
}

void doFibonacci()
{
for ( ; ; )
{
cout << "Enter a number: " << endl;
unsigned long x;
cin >> x;
try
{
cout << "Value of fibonacci number: " << Fibonacci( x) << endl;
}
catch( invalidArg<unsigned long>& inv)
{
inv.Write(x);
}
}
}
int main( )
{

doFibonacci();
system("PAUSE");
return 0;
}

Nov 5 '05 #8

"Protoman" <Pr**********@gmail.com> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
What do you mean? It uses classes and stuff.


'Classes and stuff', in themselves, do not OOP make.

-Mike
Nov 5 '05 #9
Protoman wrote:
OK then, how's my fib() funct? Is it efficient?


Well, let's critique it. First again is the chosen name. In this case,
"fib" is a English word - to fib means to lie, usually about small
things. As such, "fib" is not a great name for a class that is supposed
to perform a calculation and return an (accurate) result. This class
should be named for it does, GetNthFibonacciNumber or similar.

class fib
{
public:
unsigned long operator()(unsigned long n)
{
if(n<=0)
throw invalidArg<unsigned long>();
else if(n==1||n==2)
return 1;

unsigned long a=1, b=0;
unsigned long i=0x8000;

while (i)
{
unsigned long aa;
aa=n&i?(2*b+a)*a:a*a+b*b;
b=n&i?a*a+b*b:b*(2*a-b);
a=aa;
i>>=1;
}
return b;
}
};

Let's look at the declaration:

unsigned long operator()(unsigned long n)

Because this function is an overloaded operator, there is nothing,
another than the name of the class, "fib", to indicate what this
function does or what the "n" parameter is used for. Again, using a
named function and parameters with descriptive names would help a lot.

Let's look at these lines:

if(n<=0)
throw invalidArg<unsigned long>();
else if(n==1||n==2)
return 1;

First, we don't need the "else" since an n less than or equal to zero
will exit the routine at once. Next, since the program has eliminated
all negative numbers and zero, the if clause can be consolidated:

if(n<=0)
throw invalidArg<unsigned long>();
if(n <= 2)
return 1;

Now to the calculation itself:

unsigned long a=1, b=0;
unsigned long i=0x8000;

while (i)
{
unsigned long aa;

aa = n & i ? (2*b+a) * a : a*a+b*b;
b = n & i ? a*a+b*b: b * (2*a-b);
a = aa;
i >>= 1;
}
return b;

Now whatever this routine is doing it does look clever. But I have no
idea if it is correct, since it is not how one generally thinks of
Finbonacci numbers 0 + 1 + 1 + 2 + 3 + 5 + 8.... And again, the cryptic
variable names a, b, aa, i do not help. What I would like to see is
some comment explaining where this algorithm came from - a reference
that I could then look up to reassure myself that this code is correct
and for me to better understand it.

Now as for its efficiency: note that n & i is evaluated twice, so there
is some small room for improvement:

while (i)
{
unsigned long aa;

if (n & i)
{
aa = (2*b+a) * a ;
b = a*a+b*b;
}
else
{
aa = a*a+b*b;
b = b * (2*a-b);
}
a = aa;
i >>= 1;
}
return b;

A bigger problem is the upper limit for n. It also appears that only
the first 46 or so Fibonacci numbers can fit in 32 bits. So any
calculation with n>46 and 32 bit longs will return the wrong result. In
other words, the routine will fib.

Greg

Nov 5 '05 #10

"Protoman" <Pr**********@gmail.com> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com...
OK then, how's my fib() funct? Is it efficient?


Your function isn't efficient either....this is the comment in the Wiki
article where your code
appears....

It is essentially equivalent to the versions that employ matrix arithmetic,
but with redundant calculations eliminated. Note that this method only makes
sense for high-precision calculations where the benefit of an O(log n)
algorithm outweighs the extra complexity. Since F(48) exceeds 232 - 1, no
ordinary C program with 32-bit integers can calculate F(n) for n ? 48, and
the sophisticated algorithm in this version is just over-engineering.
Since your algorithm is only valid for the first 48, you can precompute
these values ahead of time and store them in a table.

Nov 5 '05 #11
Dave Townsend wrote:
"Protoman" <Pr**********@gmail.com> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com...
OK then, how's my fib() funct? Is it efficient?

Your function isn't efficient either....this is the comment in the Wiki
article where your code
appears....


Ouch!! I do hope Protoman wasn't going to pass that off as his own code.

john
Nov 5 '05 #12
Protoman wrote:
OK then, how's my fib() funct? Is it efficient?


If you want to generate a Fib(n) for an arbitrary value of n then it is
efficient.

On the other hand if you want to generate the series of Fibonacci
numbers, Fib(1), Fib(2), Fib(3), etc. then it is *extremely* inefficient.

So the answer to depends on what you actually want to do with Fibonacci
numbers. Something you probably haven't worked out for yourself yet.

john
Nov 5 '05 #13

Dave Townsend wrote:
"Protoman" <Pr**********@gmail.com> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com...
OK then, how's my fib() funct? Is it efficient?


Your function isn't efficient either....this is the comment in the Wiki
article where your code
appears....

It is essentially equivalent to the versions that employ matrix arithmetic,
but with redundant calculations eliminated. Note that this method only makes
sense for high-precision calculations where the benefit of an O(log n)
algorithm outweighs the extra complexity. Since F(48) exceeds 232 - 1, no
ordinary C program with 32-bit integers can calculate F(n) for n ? 48, and
the sophisticated algorithm in this version is just over-engineering.
Since your algorithm is only valid for the first 48, you can precompute
these values ahead of time and store them in a table.


OK, here's the new algorithm; it works for over 48 now:

{
if(n<=0)
throw invalidArg<unsigned long>();
else if(n<=2)
return 1;
unsigned long long a=1, b=0;
unsigned long long i=0x8000;
while (i)
{
unsigned long aa;
if (n&i)
{
aa=(2*b+a)*a;
b=a*a+b*b;
}
else
{
aa=a*a+b*b;
b=b*(2*a-b);
}
a=aa;
i>>=1;
}
return b;
}

And where should I put the try/catch statement?

Nov 5 '05 #14

Greg wrote:
(And one ohe tip: there is a "tab key on your keyboard.)


WHY DO I need the tab key for?

Nov 5 '05 #15

Dave Townsend wrote:
"Protoman" <Pr**********@gmail.com> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com...
OK then, how's my fib() funct? Is it efficient?


Your function isn't efficient either....this is the comment in the Wiki
article where your code
appears....

It is essentially equivalent to the versions that employ matrix arithmetic,
but with redundant calculations eliminated. Note that this method only makes
sense for high-precision calculations where the benefit of an O(log n)
algorithm outweighs the extra complexity. Since F(48) exceeds 232 - 1, no
ordinary C program with 32-bit integers can calculate F(n) for n ? 48, and
the sophisticated algorithm in this version is just over-engineering.
Since your algorithm is only valid for the first 48, you can precompute
these values ahead of time and store them in a table.


OK then, but is it fast?

Nov 5 '05 #16

Protoman wrote:
Greg wrote:
(And one ohe tip: there is a "tab key on your keyboard.)


WHY DO I need the tab key for?


Indentation. Improves readability and helps to verify correctness. In
other words, this code:

{
if(n<=0)
throw invalidArg<unsigned long>();
else if(n<=2)
return 1;
unsigned long long a=1, b=0;
unsigned long long i=0x8000;
while (i)
{
unsigned long aa;
if (n&i)
{
aa=(2*b+a)*a;
b=a*a+b*b;

}

should look more like:

{
if (n <= 0)
throw invalidArg<unsigned long>();
else
if (n <= 2)
return 1;

unsigned long long a=1, b=0;
unsigned long long i=0x8000;

while (i)
{
unsigned long aa;

if (n&i)
{
aa = (2*b+a)*a;
b = a*a+b*b;
}
}

Although I use the space bar for indenting code posted in messages.

Greg

Nov 5 '05 #17

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

Similar topics

10
by: KN | last post by:
I know both are pretty much the same and it comes down to personal choice. But I have to make the choice for the team. Things so far that I am considering 1. XML documentation in C# -- thats...
29
by: RAY | last post by:
Hi , my boss has asked I sit in on an interview this afternoon and that I create some interview questions on the person's experience. What is C++ used for and why would a company benefit from...
113
by: Bonj | last post by:
I was in need of an encryption algorithm to the following requirements: 1) Must be capable of encrypting strings to a byte array, and decyrpting back again to the same string 2) Must have the same...
59
by: Alan Silver | last post by:
Hello, This is NOT a troll, it's a genuine question. Please read right through to see why. I have been using Vusual Basic and Classic ASP for some years, and have now started looking at...
17
by: Brett | last post by:
I'd like references on where to find some good (quality) icons to use for form and application icons (for the EXE). Most of the free stuff isn't that great looking and there isn't a good...
15
by: Alex L Pavluck | last post by:
I am new to programming other than SAS. I read that C# is a good starting language and I have started to create some simple programs with C# 2005 express edition. Can someone let me know if this...
6
by: Jamiil | last post by:
I am not a programmer by any means, but a dedicated aficionado. I have good understanding of Java and C/C++, and now I would like to learn javascript->ajax, but I don't know where to start. My HTML...
30
by: mistral | last post by:
Neeed good javascript unescape encoder, to protect javascript code. Some advices? Online tool, or ready javascript only. Any opinions about the Javascript Obfuscator:...
244
by: Ajinkya | last post by:
Can anyone suggest me a good compiler for(c/cpp) for windows? I tried dev cpp but its debugging facility is very poor.
76
by: lorlarz | last post by:
Crockford's JavaScript, The Good Parts (a book review). This shall perhaps be the world's shortest book review (for one of the world's shortests books). I like Douglas Crockford (because I am a...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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...
0
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...
1
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
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...
0
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 ...

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.