| View previous topic :: View next topic |
| Author |
Message |
benlue Moderator
Reputation: 0
Joined: 09 Oct 2006 Posts: 2142
|
Posted: Wed Apr 11, 2007 9:04 pm Post subject: [C++] OOP? Object Oriented Programming |
|
|
This will help new C++ about something that is very useful that can save time and will generate automatically .
FAQ:
Q.I don't get what you mean ?
A.Read on then .
Q.Do i need to know C++ ?
A.Yes , of course you do .
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The Intro
This code declares a generic class and function which takes a generic parameter .
| Code: | template <typename T>
class Foo
{
T t_;
public:
Foo( T t ) : t_(t) {}
void Print_Value()
{
cout << t_ << "\n";
}
};
template <typename T>
void Print_Size( T t )
{
cout << "Size is " << sizeof(t) << "\n";
} |
To use it , you will need to specify the generic parameter like so:
| Code: | template <typename T>
class Foo
{
T t_;
public:
Foo( T t ) : t_(t) {}
void Print_Value()
{
cout << t_ << "\n";
}
};
template <typename T>
void Print_Size( T t )
{
cout << "Size is " << sizeof(t) << "\n";
}
#include <iostream>
using namespace std;
int main()
{
int i = 6;
float f = 7;
double d = 8;
Foo<int> foo_int( i );
Foo<float> foo_float( f );
Foo<double> foo_double( d );
foo_int.Print_Value();
foo_float.Print_Value();
foo_double.Print_Value();
Print_Size( i );
Print_Size( f );
Print_Size( d );
return 0;
} |
But they are all different , what will the compiler do ?
The compiler will then create a new class or function like so:
| Code: | class Foo_Int
{
int i_;
public:
Foo_Int( int i ) : i_(i) {}
void Print_Value() { cout << i_ << "\n"; }
};
class Foo_Float
{
float f_;
public:
Foo_Float( float f ) : f_(f) {}
void Print_Value() { cout << f_ << "\n"; }
};
class Foo_Double
{
double d_;
public:
Foo_Double( double d ) : d_(d) {}
void Print_Value() { cout << d_ << "\n"; }
};
void Print_Size( int i ) { cout << sizeof(int) << "\n"; }
void Print_Size( float f ) { cout << sizeof(float) << "\n"; }
void Print_Size( double d ){ cout << sizeof(double) << "\n"; } |
Keep that code stored away as you'll use it later on .
- - - - - - - - - - - - - - - - - - - - - - - - - -
FAQ:
Q.This is useless ...
A.If you already know what this does then don't read on .
- - - - - - - - - - - - - - - - - - - - - - - - - -
Evil F*&*en Macros !
So people who have been programming quite a while , know that macros are very evil and annoying .
For an example , we will use what macros used to calculate the square .
This is waht evil uses:
| Code: | | #define SQR(x) ((x) * (x)) |
Angels use templates like so to make it bug-free and safe .
| Code: | #include <iostream>
using namespace std;
template <typename T>
T SQR( T t )
{
return t * t;
}
int main()
{
int x = 2;
cout << SQR( ++x ) << "\n";
return 0;
} |
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Re-using
We will re-use a script given to me by a "friend" .
They just copied and pasted a link list , we will fix this .
Here's the original code posted by the "friend":
| Code: | // Base class for link list element
class NodeBase
{
friend class LinkList;
NodeBase *next_;
public:
NodeBase() : next_(0) {}
virtual ~NodeBase() = 0 {}
};
// Link list container
class LinkList
{
NodeBase *head_;
NodeBase *tail_;
public:
LinkList() : head_(0), tail_(0) {}
~LinkList()
{
while( 0 != head_ )
{
NodeBase *temp = head_;
head_ = head_->next_;
delete temp;
}
head_ = 0;
tail_ = 0;
}
// Appends an element to the list
void Append( NodeBase *item )
{
if ( 0 == head_ )
{
head_ = item;
tail_ = item;
}
else
{
tail_->next_ = item;
tail_ = item;
}
}
// Link list traversal methods
NodeBase* Get_Head() const { return head_; }
NodeBase* Get_Next( const NodeBase * const element ) const
{
return element->next_;
}
}; |
It may look alright , but on closer inspection , could be improved .
Lets hold the absract pointer to the abstract node item object .
| Code: | // Note: Link list container class omitted for beverity
#include <iostream>
using namespace std;
// Link list element, notice the inheritance
class Foo : public NodeBase
{
int i_;
public:
explicit Foo( int i ) : NodeBase(), i_(i) {}
friend ostream& operator<<( ostream &os, const Foo &f )
{
return os << f.i_;
}
};
int main()
{
LinkList link_list;
// add elements to link list
link_list.Append( new Foo(2) );
link_list.Append( new Foo(3) );
link_list.Append( new Foo(4) );
NodeBase *temp = link_list.Get_Head();
// prints elements in list
while ( 0 != temp )
{
Foo *f = dynamic_cast<Foo*>( temp );
cout << *f << " "; // prints 2,3,4
temp = link_list.Get_Next( temp );
}
return 0;
} |
Looks reusable .
Many problems are involved though .
-Downcast required to access list element .
When we access the link list element, we need to use to convert the base pointer downwards . The problem is may be slow . The compiler needs to search through the base inheritance graph to check validity of the downcast at runtime . It is highly impossible to get constant time downcast, especially with multiple inheritance graphs . Performance may be badly affected .
The second issue is we are violating the LSP (Liskov Substitutability Principle) . In simple terms, the LSP states that when we use base classes interfaces, we shouldn't need to know about the derived class . By using RTTI (runtime type information) downcasting, the OO design is flawed . The downcast can fail , and we need to inject additional checks (not done here) to make the program robust .
-Elements required to derive from a base .
As elements derive from a common base, we can insert any elements into any link list . Say we have another element class , we can insert that into a Foo linked list . When elements shouldn't be mixed in the same list, the compiler has no way of detecting that . It is up to the programmer's vigilance to ensure that kind of bugs doesn't happen .
This is like Java but hey , most people like C++ .
The complete fix is here using templates .
| Code: | template <typename T>
class LinkList; // forward declaration
// Generic class for link list element, no inheritance necessary
template <typename T>
class NodeBase
{
friend class LinkList<T>;
NodeBase *next_;
T t_; // generic list element stored here
public:
NodeBase() : next_(0), t_() {}
NodeBase( const T &t ) : next_(0), t_(t) {}
// access generic element
T& Get_Element() { return t_; }
};
// Link list container
template <typename T>
class LinkList
{
typedef NodeBase<T> NodeBase;
NodeBase *head_;
NodeBase *tail_;
public:
LinkList() : head_(0), tail_(0) {}
~LinkList()
{
while( 0 != head_ )
{
NodeBase *temp = head_;
head_ = head_->next_;
delete temp;
}
head_ = 0;
tail_ = 0;
}
// Appends an element to the list
void Append( const T &t )
{
NodeBase *item = new NodeBase(t);
if ( 0 == head_ )
{
head_ = item;
tail_ = item;
}
else
{
tail_->next_ = item;
tail_ = item;
}
}
// Link list traversal methods
NodeBase* Get_Head() const { return head_; }
NodeBase* Get_Next( const NodeBase * const element ) const
{
return element->next_;
}
};
#include <iostream>
using namespace std;
// No need to derive from base class
class Foo
{
int i_;
public:
explicit Foo( int i ) : i_(i) {}
friend ostream& operator<<( ostream &os, const Foo &f )
{
return os << f.i_;
}
};
int main()
{
LinkList<Foo> link_list;
link_list.Append( Foo(2) );
link_list.Append( Foo(3) );
link_list.Append( Foo(4) );
NodeBase<Foo> *temp = link_list.Get_Head();
// No downcast necessary
while ( 0 != temp )
{
cout << temp->Get_Element() << " ";
temp = link_list.Get_Next( temp );
}
return 0;
} |
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
My words
I am going to stop at that because you guys won't really need to know about the OOP polymorphism .
So enjoy an automatic safe compiling year .
FAQ:
Q. This didn't help me .
A. You need to learn more C . O.O
|
|
| Back to top |
|
 |
calvinbui Cheater
Reputation: 0
Joined: 10 Jan 2007 Posts: 32
|
Posted: Wed Apr 11, 2007 9:10 pm Post subject: |
|
|
| nice , might help my compiler produce safer codes
|
|
| Back to top |
|
 |
appalsap Moderator
Reputation: 0
Joined: 27 Apr 2006 Posts: 6753 Location: Pakistan
|
Posted: Wed Apr 11, 2007 9:11 pm Post subject: |
|
|
totally useless, you don't explain why these things can be useful and increase productivity, if you don't do that, no one will listen
also, dont use foo bar
_________________
|
|
| Back to top |
|
 |
benlue Moderator
Reputation: 0
Joined: 09 Oct 2006 Posts: 2142
|
Posted: Wed Apr 11, 2007 9:16 pm Post subject: |
|
|
| appalsap wrote: | totally useless, you don't explain why these things can be useful and increase productivity, if you don't do that, no one will listen
also, dont use foo bar | I did explain in my FAQ , that you must know C++ . You just stated that you think most people are noobs . At least you understood it .
|
|
| Back to top |
|
 |
Flyte Peanuts!!!!
Reputation: 6
Joined: 19 Apr 2006 Posts: 1887 Location: Canada
|
Posted: Fri Apr 13, 2007 8:54 pm Post subject: |
|
|
Eww, I hate classes, completely useless.
Win32 > MFC
|
|
| Back to top |
|
 |
Noz3001 I'm a spammer
Reputation: 26
Joined: 29 May 2006 Posts: 6220 Location: /dev/null
|
Posted: Sat Apr 14, 2007 5:21 pm Post subject: |
|
|
| A little OOP knowledge comes in handy.
|
|
| Back to top |
|
 |
appalsap Moderator
Reputation: 0
Joined: 27 Apr 2006 Posts: 6753 Location: Pakistan
|
Posted: Sat Apr 14, 2007 7:29 pm Post subject: |
|
|
| noz3001 wrote: | | A little OOP knowledge comes in handy. |
maybe for trivia shows
|
|
| Back to top |
|
 |
Noz3001 I'm a spammer
Reputation: 26
Joined: 29 May 2006 Posts: 6220 Location: /dev/null
|
Posted: Sat Apr 14, 2007 8:23 pm Post subject: |
|
|
| appalsap wrote: | | noz3001 wrote: | | A little OOP knowledge comes in handy. |
maybe for trivia shows |
... Knowledge is everything. The more you know the better off you will be. (Unless you know VB).
|
|
| Back to top |
|
 |
SF I'm a spammer
Reputation: 119
Joined: 19 Mar 2007 Posts: 6028
|
Posted: Mon Apr 16, 2007 9:23 pm Post subject: |
|
|
| I just learned OOP in Video Gaming for high school..confused the hell out of me at first.
|
|
| Back to top |
|
 |
lXciD Expert Cheater
Reputation: 0
Joined: 09 Feb 2006 Posts: 199 Location: SG/MY
|
Posted: Mon Apr 16, 2007 9:55 pm Post subject: |
|
|
seems like cheat engine crowd bash a lot of the OOP... too much functional and asm...
|
|
| Back to top |
|
 |
|