Tips on Creating Objects

J

JoeC

I have read books and have ideas on how to create objects. I often
create my own projects and programs. They end up getting pretty
complex and long. I often use objects in my programs they are some of
the most powerful programming tools I have found. Often times as my
program grows so do my objects. Often times I look back and see that
my objects could be broken down int several smaller more re-usable
module pieces of code. Is it a good idea to go back and make several
smaller objects out of a big object.

Here is an example:
class unit{
protected:

HWND hwnd;
coord loc;
coord currentLoc;
graphics * gr;
tbox * combatBox;
std::vector<color>colors;
std::map<char, coord> keys; //movement engine
coord n; //directions
coord s;
coord e;
coord w;
char kind;

float attack;
float dattack;
float defence;
int move;
int moved;
int dmove;
int range;
bool canmove;
bool selected;
bool mark;
bool disburse;
int col;

void create();
void displayBox(HDC, coord);
int convert(const int n){return n * 16;}

public:
unit();
unit(HWND,graphics*,int,int,int);
unit(HWND,graphics*,int,int,int,int,int);
unit(HWND,graphics*,DWORD,float, float, int, int, int);
unit(HWND,graphics*,DWORD,float, float, int, int, int, bool);
unit(unit*);
~unit();

DWORD sideColor(){return colors[0].getCode();}
int intAttack(){return attack;}
int intDefence(){return defence;}
float Attack(){return attack;}
float Defence(){return defence;}
int Moved(){return moved;}

void display(HDC); //display at crrent loc
void display(HDC, int, int); //display at specific loc
void display(HDC, int); //display with offset for stacking
void displayBig(HDC, int, int);
void change(HWND);
void update(HWND, coord);

coord nextCoord(char);
void mover(coord&, int);
void reset();
void tomark(); //marks unit for death;
bool marked(){return mark;}
coord getCoord(){return loc;}
coord getCurrent(){return currentLoc;}
bool canMove(){return canmove;}
bool isSelect(){return selected;}
bool inRange(coord);
void selectOn(){selected = true;}
void selectOff(){selected = false;}
void isArt(){range = 12;}
void cBoxOn(){combatBox = new tbox;};
void disbersed();
void unDisberse(){disburse = false;}
void write(std::eek:fstream&);
void load(std::ifstream&);
void addk(char k){kind = k;}
};


This is a unit for my game. Basically it is a single game piece.

It does everything I want the unit to do. It has a graphic color it
can fight and move.

It could be graphical.
It could be movable.
It can fight.

I have my has a:

Should I create a graphical that does the graphics
a movable that does the movement and fight-able
because it fights.

Later I could use those simpler types for things in my game that are
graphics but don't move or units that don't fight. I come to this
from experience. I don't want to go back and start editing an object
that works. For my next project I can create these simpler objects
and build more complex ones.
 
D

Dave Rahardja

This is a unit for my game. Basically it is a single game piece.

It does everything I want the unit to do. It has a graphic color it
can fight and move.

It could be graphical.
It could be movable.
It can fight.

I have my has a:

Should I create a graphical that does the graphics
a movable that does the movement and fight-able
because it fights.

Later I could use those simpler types for things in my game that are
graphics but don't move or units that don't fight. I come to this
from experience. I don't want to go back and start editing an object
that works. For my next project I can create these simpler objects
and build more complex ones.

You're on the right track. Basically you'd want to work on defining interfaces
that your classes can support.

Here's a hint: interfaces basically have only public pure virtual functions.
So a "displayable" interface may have an interface like this:

class displayable
{
public:
virtual void display(HDC) = 0; //display at crrent loc
virtual void display(HDC, int, int) = 0; //display at specific loc
virtual void display(HDC, int) = 0; //display with offset for stacking
// etc
};

Then your classes implement the interface by inheriting from them and
providing the definitions for the pure virtual functions.

Creating interfaces allows you to think about specific problem domains (in
this case, rendering graphics). To get the full benefit, the algorithms that
work with your interface must also work strictly with pointers or references
to that interface, regardless of the actual classes of the objects it works
with at runtime.

-dr
 
G

Grizlyk

JoeC said:
Should I create a graphical that does the graphics
a movable that does the movement and fight-able
because it fights.

To make good classes is not a easy work:
1. The high-level casses must reflect your "job area" - expert of the "job
area" must be able to work with classes of your programs - create objects
that have a sence in "job area" and send them a messages, that have a sence
there too. For example

Tlandscape &meadow= *new Tlandscape;

meadow.has(new Tgrass + new Tpine(3)+ new Tlake );
enum{ grass=0, pines, lake};
meadow[lake].has( new Tfish(100) );

Tperson &worker=*new Tworker;

worker.making(meadow.east, new Tditch);
const uint ditch=lake+1;

Note, the example does not intend to be only way to create landscapes, but
shows, that any man, who works with landscapes can undersand what the part
of program is going to do.

2. The base-level classes must be re-usable. Try "design paterns" to build
your classes as re-usable.
 
J

JoeC

You're on the right track. Basically you'd want to work on defining interfaces
that your classes can support.

Here's a hint: interfaces basically have only public pure virtual functions.
So a "displayable" interface may have an interface like this:

class displayable
{
public:
virtual void display(HDC) = 0; //display at crrent loc
virtual void display(HDC, int, int) = 0; //display at specific loc
virtual void display(HDC, int) = 0; //display with offset for stacking
// etc

};

Then your classes implement the interface by inheriting from them and
providing the definitions for the pure virtual functions.

Creating interfaces allows you to think about specific problem domains (in
this case, rendering graphics). To get the full benefit, the algorithms that
work with your interface must also work strictly with pointers or references
to that interface, regardless of the actual classes of the objects it works
with at runtime.

-dr

I know about virtual functions and how to use them. In most cases I
choose not to use them because of the duplication of effort. My units
have potential virtual functions for air and sea units. They have the
same properties but may be implemented in a different way. For
example grounds units can't move in water but water units can't move
on ground.

I am trying to get more of a thought process. I usually can figure
out syntax but the real challenge is designing my programs. I
understand that you need experience to design good objects but you
have to write objects to get that experience. I have read the advice
given in some books but I am just trying to find out how to go about
creating objects better. I read that you should design an object for
a purpose not to work with your program. My worry is taking a
perfectly good object and messing it up. The object was designed to
work as a unit and the different function may not function if they are
seperated. I my object fine and not too big.
 
J

JoeC

JoeC said:
Should I create a graphical that does the graphics
a movable that does the movement and fight-able
because it fights.

To make good classes is not a easy work:
1. The high-level casses must reflect your "job area" - expert of the "job
area" must be able to work with classes of your programs - create objects
that have a sence in "job area" and send them a messages, that have a sence
there too. For example

Tlandscape &meadow= *new Tlandscape;

meadow.has(new Tgrass + new Tpine(3)+ new Tlake );
enum{ grass=0, pines, lake};
meadow[lake].has( new Tfish(100) );

Tperson &worker=*new Tworker;

worker.making(meadow.east, new Tditch);
const uint ditch=lake+1;

Note, the example does not intend to be only way to create landscapes, but
shows, that any man, who works with landscapes can undersand what the part
of program is going to do.

2. The base-level classes must be re-usable. Try "design paterns" to build
your classes as re-usable.

--
Maksim A. Polyanin

"In thi world of fairy tales rolls are liked olso"
/Gnume/

Is this C++? This doesn't look like the code I use, still I follow
it. I do read books on how to create good code but when I write my
own material and basically, I write one thing as a single object. I
would like to write good base classes but the I tend to just keep
adding new functions to my existing classes. I posted an example of
how I can write this class better. I am have heard about design
patterns but not sure what that means and how it relates to the
programs that I write. I wrote a war/board game and I did learn a
great deal from that game but how could I use a design pattern for
this object. I have about 20 objects in the game I wrote. I don't
use inheritance much, I do use it when I create a graphic board from a
board:

class board{
protected:
static const int xlen = 30; //size of the board
static const int ylen = 20;
int b[ylen][xlen]; //map grid
void create();
ifstream& cfill(ifstream& in, int& code); /*Reads map from file */
void fill();
public:
board();
int GetSpace(const int y, const int x){return b[y][x];}//gets the
//terrain number of the grid
int GetSizeX(){return xlen;} //gets size of grid
int GetSizeY(){return ylen;}

};


class graphicBoard : public board{

HWND hwnd;
graphics * gr;


static const int terainTypes = 5;

int mvf[terainTypes];
char * tn[5];

color colors[terainTypes];
int mf[terainTypes];
void fillGraphics();
void fillMapColors();
void fillTerain();
void fillMoveFactors();
int convert(int n){return n*16;}
int getLocer(coord c){return b[c.x][c.y];}

public:

graphicBoard(HWND);
~graphicBoard();
void displayBoard(HDC);
int movefactor(coord);
int movefactor(int, int);
char* terainName(const coord&);
void showName(HDC, coord);
};
 
G

Grizlyk

JoeC said:
Should I create a graphical that does the graphics
a movable that does the movement and fight-able
because it fights.

To make good classes is not a easy work:
1. The high-level casses must reflect your "job area" - expert of the
"job
area" must be able to work with classes of your programs - create objects
that have a sence in "job area" and send them a messages, that have a
sence
there too. For example

Tlandscape &meadow= *new Tlandscape;

meadow.has(new Tgrass + new Tpine(3)+ new Tlake );
enum{ grass=0, pines, lake};
meadow[lake].has( new Tfish(100) );

Tperson &worker=*new Tworker;

worker.making(meadow.east, new Tditch);
const uint ditch=lake+1;

Note, the example does not intend to be only way to create landscapes,
but
shows, that any man, who works with landscapes can undersand what the
part
of program is going to do.

2. The base-level classes must be re-usable. Try "design paterns" to
build
your classes as re-usable.
Is this C++? This doesn't look like the code I use, still I follow
it.

I think C++ really needs extra language information placed into class
declaration
to be bridge to OO design stuffs, like text-looking macro sources (that
"looks like not C++"),
class oriented IDE and other.

But my previous example, of course, is pure OO C++, just add "*" befor
"new".
Take the following simplest compileable example - (copy & paste it inlo
file)

I know, the example can be implemented better, but i just tryed to show that
source example, that "looks for you like not C++", is really C++ code.

Note:
I have rufused from std::auto_prt using, because I can not predict its
behaviuor.

I have tired to fight with unexpected std::auto_prt limitations and
including already published Ntest::Tauto_ptr as replacement to allow the
example
to be at least compiled.

If stdlib uses objects sequentally (and will not try to do "double-move")
all will work,
if not, you need working with stdlib conventions.

- cut here -

#include <typeinfo>
#include <exception>
#include <memory>
#include <list>

//sorry, but
#include <stdio.h>

// ******************
// ******************
namespace Ntest{

using std::bad_cast;

//{
//using std::auto_ptr;
//using std::auto_ptr_ref;

//C++ still not support
#define heap
#define array //heap[]
#define _auto

#define ctor
#define dtor
#define after(x)
#define befor(x)
#define once
#define probe

#define memtype

// *****************
template<class Tobj>
class Tarray
{
public:
//C++ still not support
//typedef array memtype;

Tobj array* ptr;

public:
void detach(){ ptr=0; }
void destroy(){ if(ptr)delete[] ptr; ptr=0; }

void replace(Tobj array* p)
{
if( p != ptr )
{
if(ptr)delete[] ptr;
ptr=p;
}
}

Tobj array* move()
{
Tobj array *const tmp=ptr;
ptr=0;
return tmp;
}

public:
Tarray(Tobj array* p=0):ptr(p){}
};

// *****************
template<class Tobj>
class Tobject
{
public:
//C++ still not support
//typedef heap memtype;

Tobj heap* ptr;

public:
void detach(){ ptr=0; }
void destroy(){ if(ptr)delete ptr; ptr=0; }

void replace(Tobj heap* p)
{
if( p != ptr )
{
if(ptr)delete ptr;
ptr=p;
}
}

Tobj heap* move()
{
Tobj heap* const tmp=ptr;
ptr=0;
return tmp;
}

public:
Tobject(Tobj heap* p=0):ptr(p){}
};

// *****************
template<class Tobj>
class Tadr
{
public:
//C++ still not support
//typedef _auto memtype;
//typedef Tobj _auto* memtype;

Tobj _auto* ptr;

public:
void detach(){ ptr=0; }
void destroy(){ ptr=0; }
void replace(Tobj _auto* p){ ptr=p; }

Tobj _auto* move()
{
Tobj _auto* const tmp=ptr;
ptr=0;
return tmp;
}

public:
Tadr(Tobj _auto* p=0):ptr(p){}
};

//}

//{
// **********************************************
template<class Tobj, class Tmemory=Tobject<Tobj> >
class Tauto_ptr
{
mutable Tmemory memory;
//typedef typename Tmemory::memtype memtype;

Tauto_ptr& set_ptr(Tobj memtype* const new_adr)
{
memory.replace(new_adr);
return *this;
}

void created()
{
#ifdef MY_DBG
printf("%p: created\n",this);
#endif
}

public:
char is_ptr_assigned()const probe { return memory.ptr? 1:0; }

Tobj _auto* get_ptr()const after(set_ptr||created) { return
static_cast<Tobj _auto*>(memory.ptr); }
Tauto_ptr& replace(Tobj memtype* const new_adr)ctor { return
set_ptr(new_adr); }
Tobj memtype* move()const dtor { return memory.move(); }
void detach()const dtor { memory.detach(); }

public:
Tobj& get_obj()const { if(!memory.ptr)throw bad_cast(); return
*get_ptr(); }

Tobj& operator* ()const { return get_obj(); }
Tobj _auto* operator-> ()const { return &get_obj(); }

Tobj& operator() ()const { return get_obj(); }
Tobj _auto* operator() (const int)const { return get_ptr(); }

Tauto_ptr& operator= (Tobj heap* const new_adr)ctor { return
replace(new_adr); }

public:
Tauto_ptr(Tobj memtype* p=0):memory(p){created();}
//move construction
Tauto_ptr(const Tauto_ptr& obj):memory(obj.move()){created();}
//move assignment
Tauto_ptr& operator= (const Tauto_ptr& obj)ctor
{
if( &obj != this ){ replace(obj.move()); }
return *this;
}
~Tauto_ptr()
{
memory.destroy();
#ifdef MY_DBG
printf("%p: destroyed\n",this);
#endif
}
};
//}

// ******************
// ******************
using std::list;

typedef unsigned int uint;

void greetings(const char* const msg, void *const ptr, const char* const
what="created"){printf("%p: Hello, i am %s, just %s!\n",ptr,msg,what);}
void bye(void *const ptr){printf("%p: Bye.\n",ptr);}

// ******************
// ******************
template<class T>
class Tseq
{
public:
//typedef auto_ptr<T> Tptr;
//typedef auto_ptr_ref<T> Tptr_ref;
typedef Tauto_ptr<T> Tptr;
typedef Tptr Tptr_ref;

typedef list<Tptr> list;
typedef typename list::iterator iterator;
typedef typename list::const_iterator const_iterator;

T& operator[] (const uint)const;

T& operator+ (T& obj)
{
assigned.push_back(Tptr_ref(&obj));
return static_cast<T&>(*this);
}

T& has(T& obj)
{
tree.push_back(Tptr_ref(&obj));
//tree.merge(obj.assigned);
add_list(obj);
return static_cast<T&>(*this);
}

T& remake(T& obj)
{
tree.clear();
return has(obj);
}

protected:
Tseq(){}

protected:
list tree;
list assigned;

void add_list(T& obj);

private:
Tseq(const Tseq&);
Tseq& operator= (const Tseq&);
};

// ******************
class Tlandscape: public Tseq<Tlandscape>
{
public:
Tlandscape& east;

public:
Tlandscape():east(*this){ greetings("landscape",this); }
~Tlandscape(){bye(this);}

protected:
Tlandscape(const char *const msg, const char* const
what="created"):east(*this){ greetings(msg,this,what); }
};

// ******************
const char* make_name(char *const msg);

// ******************
// ******************
class Tgrass: public Tlandscape
{
public:
Tgrass():Tlandscape("grass"){}
};

// ******************
class Tditch: public Tlandscape
{
public:
Tditch():Tlandscape("ditch 10x10"){}
};

// ******************
// ******************
class Tpine: public Tlandscape
{
public:
Tpine():Tlandscape( make_name(msg) ){}

explicit Tpine(const uint num): Tlandscape( make_name(msg) )
{
if(!num)throw bad_cast();
if(num==1)return;

for(uint i=num-1; i; --i){ has(*new Tpine);}
}

protected:
static char msg[15];
};

// ******************
class Tlake: public Tlandscape
{
public:
Tlake():Tlandscape(make_name(msg)){}
explicit Tlake(const uint num): Tlandscape( make_name(msg) )
{
if(!num)throw bad_cast();
if(num==1)return;

for(uint i=num-1; i; --i){ has(*new Tlake);}
}

protected:
static char msg[15];
};

// ******************
class Tfish: public Tlandscape
{
public:
Tfish():Tlandscape(make_name(msg)){}
explicit Tfish(const uint num): Tlandscape( make_name(msg) )
{
if(!num)throw bad_cast();
if(num==1)return;

for(uint i=num-1; i; --i){ has(*new Tfish);}
}

protected:
static char msg[15];
};

// ******************
// ******************
class Tperson
{
public:
virtual void making(Tlandscape& dst, Tlandscape& src)=0;
virtual ~Tperson(){bye(this);}

protected:
//Tperson(){ greetings("person",this); }
Tperson(const char *const msg, const char* const what="come in"){
greetings(msg,this,what); }

private:
Tperson(const Tperson&);
Tperson& operator= (const Tperson&);
};

// ******************
class Tworker: public Tperson
{
public:
virtual void making(Tlandscape& dst, Tlandscape& src){ dst.has(src); }

public:
Tworker():Tperson("worker"){}
};

// ******************
// ******************
//namespace Ntest
}

// ******************
// ******************
using namespace Ntest;

char Tpine::msg[15]="pine #000";
char Tlake::msg[15]="lake #000";
char Tfish::msg[15]="fish #000";

// ******************
const char* Ntest::make_name(char *const msg)
{
if(!msg)throw bad_cast();

enum{ num_chars=3 };
const uint len=strlen(msg); if(len<num_chars)throw bad_cast();
char *const p=msg+len-num_chars;

++p[num_chars-1];
for(uint i=1; i<num_chars; ++i)
{
if( p[num_chars-i]>0x39 ){ p[num_chars-i]=0x30; ++p[num_chars-i-1]; };
}
if( p[0]>0x39 )p[0]=0x30;

return msg;
}

// ******************
template<class T>
T& Tseq<T>::eek:perator[] (const uint idx)const
{
if( tree.empty() )throw bad_cast();

const_iterator it=tree.begin();
const_iterator end=tree.end();

for(uint i=idx; i; --i)
{
++it;
if(it==end)throw bad_cast();
}
return **it;
}

// ******************
//tree.merge(obj.assigned);
template<class T>
void Tseq<T>::add_list(T& obj)
{
iterator it=obj.assigned.begin();
iterator end=obj.assigned.end();

while(it!=end)
{
//tree.push_back( Tptr_ref( it->release() ) );
tree.push_back( Tptr_ref( *it ) );
++it;
}
obj.assigned.clear();
}

// ******************
// ******************
int main()
{
try{

//original example start
Tlandscape &meadow= *new Tlandscape;

meadow.has(*new Tgrass + *new Tpine(3)+ *new Tlake );
enum{ grass=0, pines, lake};
//100 is too much to place messages on screen, take a 5
//meadow[lake].has( *new Tfish(100) );
meadow[lake].has( *new Tfish(5) );

Tperson &worker=*new Tworker;

worker.making(meadow.east, *new Tditch);
const uint ditch=lake+1;

//original example end
delete &worker;
delete &meadow;

}
catch(bad_cast&){fprintf(stderr,"error: %s","bad_cast");}
catch(...){fprintf(stderr,"error: %s","unknown");}

}

- cut here -
 
J

JoeC

y previous example, of course, is pure OO C++, just add "*" befor
"new".
Take the following simplest compileable example - (copy & paste it inlo
file)

I know, the example can be implemented better, but i just tryed to show that
source example, that "looks for you like not C++", is really C++ code.

Note:
I have rufused from std::auto_prt using, because I can not predict its
behaviuor.

I have tired to fight with unexpected std::auto_prt limitations and
including already published Ntest::Tauto_ptr as replacement to allow the
example
to be at least compiled.

If stdlib uses objects sequentally (and will not try to do "double-move")
all will work,
if not, you need working with stdlib conventions.

- cut here -

#include <typeinfo>
#include <exception>
#include <memory>
#include <list>

//sorry, but
#include <stdio.h>

// ******************
// ******************
namespace Ntest{

using std::bad_cast;

//{
//using std::auto_ptr;
//using std::auto_ptr_ref;

//C++ still not support
#define heap
#define array //heap[]
#define _auto

#define ctor
#define dtor
#define after(x)
#define befor(x)
#define once
#define probe

#define memtype

// *****************
template<class Tobj>
class Tarray
{
public:
//C++ still not support
//typedef array memtype;

Tobj array* ptr;

public:
void detach(){ ptr=0; }
void destroy(){ if(ptr)delete[] ptr; ptr=0; }

void replace(Tobj array* p)
{
if( p != ptr )
{
if(ptr)delete[] ptr;
ptr=p;
}
}

Tobj array* move()
{
Tobj array *const tmp=ptr;
ptr=0;
return tmp;
}

public

Intersting code. What is it supposed to do?

All I know is what I read in books and created from experience. I am
not into writing low leve library kind of stuff. I am trying to use
the experience I have with the programs that I wrote and implement
better design. I read things in books and I write my own programs. I
am trying to learn better technique to write better programs. I have
some experience but am no professional. My biggest problem is that I
am completely self taught and the only way is if I read books or ask
questions. I am trying to get some advice in writing better objects.
It doesn't have to be perfect OO but I am trying to do better. I know
that OO deals with virtual functions and inhereance. I use that if I
want to sick simmiliar objects in the same container because most OO
stuff is duplication of work.
 
G

Grizlyk

JoeC said:
Intersting code. What is it supposed to do?

You have said, that the code
Tlandscape &meadow= *new Tlandscape;

meadow.has(new Tgrass + new Tpine(3)+ new Tlake );
enum{ grass=0, pines, lake};
meadow[lake].has( new Tfish(100) );

Tperson &worker=*new Tworker;

worker.making(meadow.east, new Tditch);
const uint ditch=lake+1;

does not looks like C++ for you. I have posted the complete compileable
example just to prove that it is pure C++ code. For OO desined programs, you
can safely ignore all code implementing target example, and class Tarray
// *****************
template<class Tobj>
class Tarray

is the code, which can be safely ignored if you do not want to understand
it. If you need to dig implementation of any library to use it, the library
at least is not OO code.
 
J

JoeC

JoeC said:
Intersting code. What is it supposed to do?

You have said, that the code
Tlandscape &meadow= *new Tlandscape;
meadow.has(new Tgrass + new Tpine(3)+ new Tlake );
enum{ grass=0, pines, lake};
meadow[lake].has( new Tfish(100) );
Tperson &worker=*new Tworker;
worker.making(meadow.east, new Tditch);
const uint ditch=lake+1;

does not looks like C++ for you. I have posted the complete compileable
example just to prove that it is pure C++ code. For OO desined programs, you
can safely ignore all code implementing target example, and class Tarray
// *****************
template<class Tobj>
class Tarray

is the code, which can be safely ignored if you do not want to understand
it. If you need to dig implementation of any library to use it, the library
at least is not OO code.

--
Maksim A. Polyanin

"In thi world of fairy tales rolls are liked olso"
/Gnume/

I get it very interesting. It is a better way to do what I am doing.
I understand most of what you are doing. I have written a program
with a certain amount of knowledge and this is above me. I would
like to be able to incorporate techniques like that but I have to get
there. The resources I have lead me to program as I do. For me I am
totally self taught from books and experience. I see programming as a
series of steps. I would like a resource that will take me through
the steps in creating an object like that. I have displayed the
objects I created, that is about the best I can do. I don't expect a
detail explanation of how an why an object like that is created but
where I can find that information.

Most of the programming book I see teach how to write code it is tough
finding books that show the best way to implement that code.

Tperson &worker=*new Tworker;
meadow[lake].has( new Tfish(100) );

I haven't even seen lines like these in any of my books. normally I
would use theperson * worker new tworker,
have not seen fun(new var(num));

If I have seen them I haven't used them or seen a need. This is as
far as I have gotten with OO programming:

class hunit{

unit * p;
int * cnt;
public:
hunit() : cnt(new int(1)), p(new unit) {}
hunit(char);
hunit(const hunit& u) : cnt(u.cnt), p(u.p) {++*cnt;}
hunit& operator = (const hunit&);
hunit(std::istream);
~hunit();
void move();
void attack();
void display();
};

class unit{
protected:
int locx;
int locy;

int atk;
int dfce;
void create();
public:
unit();
unit(std::istream);
virtual ~unit(){};
virtual unit* copy() const;
virtual void move();
virtual void attack();
virtual void display();
};


I wrote this to learn how to use virtual functions and put them in a
vector. I have to study to get more complicated then this. I have
learned so good techniques but I still have a ways to go. Again I
wouldn't mid some tips to make my objects better but I think you are
suggesting too much. That requires some hard core studying with a
good book. If you can break some advice down to a paragraph or two on
ways to approach creation of an object that would be great.

I do read books and I get the approach of the author but it is also
good to get thoughts of others who do this kind of programming. I
understand once those habits are created they become second nature. I
would like to get to that point but I have to learn step by step. I
would like a few things to take away and make my program better.

I have my game posted at: it is SBGII.7 under complete games.
http://groups.msn.com/cgameprogramming

Any feedback on my code would be great. Before I wrote this I got
some feedback on my simple board game I and they were small nit pickey
thing but I took the advice and it really helped me.
 
G

Grizlyk

JoeC said:
Tperson &worker=*new Tworker;
meadow[lake].has( new Tfish(100) );

I haven't even seen lines like these in any of my books. normally I
would use theperson * worker new tworker,

The following expressions are equal by logic

Tperson *const worker= new Tworker;
Tperson &worker= *new Tworker;
have not seen fun(new var(num));

If "fun" and "var" are class name , the "fun(new var(num))" is constructor,
declared as

#define heap //means created by "new"
fun::fun(var heap* p);

typedef int num;
var::var(const num);
 
A

andrewmcdonagh

I have read books and have ideas on how to create objects. I often
create my own projects and programs. They end up getting pretty
complex and long. I often use objects in my programs they are some of
the most powerful programming tools I have found. Often times as my
program grows so do my objects. Often times I look back and see that
my objects could be broken down int several smaller more re-usable
module pieces of code. Is it a good idea to go back and make several
smaller objects out of a big object.

Here is an example:
class unit{
protected:

HWND hwnd;
coord loc;
coord currentLoc;
graphics * gr;
tbox * combatBox;
std::vector<color>colors;
std::map<char, coord> keys; //movement engine
coord n; //directions
coord s;
coord e;
coord w;
char kind;

float attack;
float dattack;
float defence;
int move;
int moved;
int dmove;
int range;
bool canmove;
bool selected;
bool mark;
bool disburse;
int col;

void create();
void displayBox(HDC, coord);
int convert(const int n){return n * 16;}

public:
unit();
unit(HWND,graphics*,int,int,int);
unit(HWND,graphics*,int,int,int,int,int);
unit(HWND,graphics*,DWORD,float, float, int, int, int);
unit(HWND,graphics*,DWORD,float, float, int, int, int, bool);
unit(unit*);
~unit();

DWORD sideColor(){return colors[0].getCode();}
int intAttack(){return attack;}
int intDefence(){return defence;}
float Attack(){return attack;}
float Defence(){return defence;}
int Moved(){return moved;}

void display(HDC); //display at crrent loc
void display(HDC, int, int); //display at specific loc
void display(HDC, int); //display with offset for stacking
void displayBig(HDC, int, int);
void change(HWND);
void update(HWND, coord);

coord nextCoord(char);
void mover(coord&, int);
void reset();
void tomark(); //marks unit for death;
bool marked(){return mark;}
coord getCoord(){return loc;}
coord getCurrent(){return currentLoc;}
bool canMove(){return canmove;}
bool isSelect(){return selected;}
bool inRange(coord);
void selectOn(){selected = true;}
void selectOff(){selected = false;}
void isArt(){range = 12;}
void cBoxOn(){combatBox = new tbox;};
void disbersed();
void unDisberse(){disburse = false;}
void write(std::eek:fstream&);
void load(std::ifstream&);
void addk(char k){kind = k;}

};

This is a unit for my game. Basically it is a single game piece.

It does everything I want the unit to do. It has a graphic color it
can fight and move.

It could be graphical.
It could be movable.
It can fight.

I have my has a:

Should I create a graphical that does the graphics
a movable that does the movement and fight-able
because it fights.

Later I could use those simpler types for things in my game that are
graphics but don't move or units that don't fight. I come to this
from experience. I don't want to go back and start editing an object
that works. For my next project I can create these simpler objects
and build more complex ones.

Two of the best design approaches I've used for a number of years now,
is to make my classes conform to the 'Single Responsibility Principle'
and the 'Open Closed Principle'

Google both of these terms and you will find numerous sources of info
on them.

Applying these two design principles leads us to create many small
classes, instead of few large classes and the flexibility of the
design that ensues from it, are hugely beneficial.

HTH

Andrew
 
J

JoeC

I have read books and have ideas on how to create objects. I often
create my own projects and programs. They end up getting pretty
complex and long. I often use objects in my programs they are some of
the most powerful programming tools I have found. Often times as my
program grows so do my objects. Often times I look back and see that
my objects could be broken down int several smaller more re-usable
module pieces of code. Is it a good idea to go back and make several
smaller objects out of a big object.
Here is an example:
class unit{
protected:
HWND hwnd;
coord loc;
coord currentLoc;
graphics * gr;
tbox * combatBox;
std::vector<color>colors;
std::map<char, coord> keys; //movement engine
coord n; //directions
coord s;
coord e;
coord w;
char kind;
float attack;
float dattack;
float defence;
int move;
int moved;
int dmove;
int range;
bool canmove;
bool selected;
bool mark;
bool disburse;
int col;
void create();
void displayBox(HDC, coord);
int convert(const int n){return n * 16;}
public:
unit();
unit(HWND,graphics*,int,int,int);
unit(HWND,graphics*,int,int,int,int,int);
unit(HWND,graphics*,DWORD,float, float, int, int, int);
unit(HWND,graphics*,DWORD,float, float, int, int, int, bool);
unit(unit*);
~unit();
DWORD sideColor(){return colors[0].getCode();}
int intAttack(){return attack;}
int intDefence(){return defence;}
float Attack(){return attack;}
float Defence(){return defence;}
int Moved(){return moved;}
void display(HDC); //display at crrent loc
void display(HDC, int, int); //display at specific loc
void display(HDC, int); //display with offset for stacking
void displayBig(HDC, int, int);
void change(HWND);
void update(HWND, coord);
coord nextCoord(char);
void mover(coord&, int);
void reset();
void tomark(); //marks unit for death;
bool marked(){return mark;}
coord getCoord(){return loc;}
coord getCurrent(){return currentLoc;}
bool canMove(){return canmove;}
bool isSelect(){return selected;}
bool inRange(coord);
void selectOn(){selected = true;}
void selectOff(){selected = false;}
void isArt(){range = 12;}
void cBoxOn(){combatBox = new tbox;};
void disbersed();
void unDisberse(){disburse = false;}
void write(std::eek:fstream&);
void load(std::ifstream&);
void addk(char k){kind = k;}

This is a unit for my game. Basically it is a single game piece.
It does everything I want the unit to do. It has a graphic color it
can fight and move.
It could be graphical.
It could be movable.
It can fight.
I have my has a:
Should I create a graphical that does the graphics
a movable that does the movement and fight-able
because it fights.
Later I could use those simpler types for things in my game that are
graphics but don't move or units that don't fight. I come to this
from experience. I don't want to go back and start editing an object
that works. For my next project I can create these simpler objects
and build more complex ones.

Two of the best design approaches I've used for a number of years now,
is to make my classes conform to the 'Single Responsibility Principle'
and the 'Open Closed Principle'

Google both of these terms and you will find numerous sources of info
on them.

Applying these two design principles leads us to create many small
classes, instead of few large classes and the flexibility of the
design that ensues from it, are hugely beneficial.

HTH

Andrew

This is what I was looking for. I found some good articles that I
think could be very helpful. It is good to see how to do things but
for me why is far more important and useful.
 
A

andrewmcdonagh

On Feb 11, 12:04 pm, "andrewmcdonagh" <[email protected]>
wrote:






This is what I was looking for. I found some good articles that I
think could be very helpful. It is good to see how to do things but
for me why is far more important and useful.

Glad to help

Andrew
 
D

Dave Rahardja

Two of the best design approaches I've used for a number of years now,
is to make my classes conform to the 'Single Responsibility Principle'
and the 'Open Closed Principle'

Google both of these terms and you will find numerous sources of info
on them.

Applying these two design principles leads us to create many small
classes, instead of few large classes and the flexibility of the
design that ensues from it, are hugely beneficial.

Indeed. Also look up "Liskov Substitution Principle" as well. I can't tell you
how many "real world" programs I've worked on that got itself into a tangle
because it broke LSP early on in the design.

Many times new OO developers are frightened by the number of files that are
generated when he follows good OO decomposition principles. But he'll be
thankful when he starts reusing classes.

-dr
 
J

JoeC

Indeed. Also look up "Liskov Substitution Principle" as well. I can't tell you
how many "real world" programs I've worked on that got itself into a tangle
because it broke LSP early on in the design.

Many times new OO developers are frightened by the number of files that are
generated when he follows good OO decomposition principles. But he'll be
thankful when he starts reusing classes.

-dr

I know the basics of doing OO programming and the number of files and
duplication of code seems intimidating. I will look at this material
and see how it can help me. I have always read that using virtual
functions and dynamic binding solve certian problems.
 
D

Dave Rahardja

I know the basics of doing OO programming and the number of files and
duplication of code seems intimidating. I will look at this material
and see how it can help me. I have always read that using virtual
functions and dynamic binding solve certian problems.

Duplication of code should almost NEVER appear in a well-analyzed program.

Here's a great resource for the key OO principles to understand:

http://www.objectmentor.com/omSolutions/oops_what.html

-dr
 
R

Richard Herring

JoeC said:
Intersting code. What is it supposed to do?

You have said, that the code
Tlandscape &meadow= *new Tlandscape;

meadow.has(new Tgrass + new Tpine(3)+ new Tlake );
enum{ grass=0, pines, lake};
meadow[lake].has( new Tfish(100) );

Tperson &worker=*new Tworker;

worker.making(meadow.east, new Tditch);
const uint ditch=lake+1;

does not looks like C++ for you. I have posted the complete compileable
example just to prove that it is pure C++ code.

So what does your compiler say when you try to sum three pointers?
 
J

JoeC

Duplication of code should almost NEVER appear in a well-analyzed program.

Here's a great resource for the key OO principles to understand:

http://www.objectmentor.com/omSolutions/oops_what.html

-dr

Thanks, I had found some of the articles from the key words I got.
Most of what I have comes from books that don't go too much into the
topic. This is a dificult concept to understand I would like to get
as many points of view as possible,
 
G

Grizlyk

Richard said:
You have said, that the code
Tlandscape &meadow= *new Tlandscape;

meadow.has(new Tgrass + new Tpine(3)+ new Tlake );
enum{ grass=0, pines, lake};
meadow[lake].has( new Tfish(100) );

Tperson &worker=*new Tworker;

worker.making(meadow.east, new Tditch);
const uint ditch=lake+1;

does not looks like C++ for you. I have posted the complete compileable
example just to prove that it is pure C++ code.

So what does your compiler say when you try to sum three pointers?

copy&paste to your compiler the example in message above
 
J

JoeC

JoeC said:
Tperson &worker=*new Tworker;
meadow[lake].has( new Tfish(100) );
I haven't even seen lines like these in any of my books. normally I
would use theperson * worker new tworker,

The following expressions are equal by logic

Tperson *const worker= new Tworker;
Tperson &worker= *new Tworker;
have not seen fun(new var(num));

If "fun" and "var" are class name , the "fun(new var(num))" is constructor,
declared as

#define heap //means created by "new"
fun::fun(var heap* p);

typedef int num;
var::var(const num);

--
Maksim A. Polyanin

"In thi world of fairy tales rolls are liked olso"
/Gnume/

I read through some of those articles you suggested. They were
interesting but I have some questions. How small should an object
be. From some of the examples it is almost to each variable should be
a class. I posted some of my work and I was hoping to get some ideas
on how I could break my classes down a bit. I have some ideas but I
was hoping to get a second opinion.

what is wrong with a constructor ? obj::eek:bj(int, int, char); What is
the advantage of creating structures obj::eek:bj(strc&);

I will try to begin re-writing my classes and breaking them down to
smaller parts. I don't have that much to go on to help me with my
design. I think graphical, movable, attackable, defndable.

Is it ok to have a class:

class unit : public movable, attackable, graphical, ..... To build a
class? If you look at my objects they are pretty big and do quite a
bit. They move, fight, display, become disbersed, have colors and
graphics.
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top