Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old July 19th, 2005, 08:39 PM
forums_mp
Guest
 
Posts: n/a
Default implementation details

After reading a few texts - nameley koeing/moo and eckel - I decided
to investigating the importance of templates. Of course there's no
substitute for practice so I figured I try a simple program.

That said I'm interested in suggestions for improvement on the
template class (be gracious i'm slowly coming up to speed in ++ :))
but more importantly I have a few questions.
For starters, in an ideal world each call to Store should be followed
by a subsequent Retrieve. If however, Store was called twice before a
Retrieve then I'd like to implement some sort of overrun check. I
suspect this could be handled with an overrun_count that'll get
incremented in Store and decremented in Retrieve or (implementation
help here)???

Conceptually I understand teh copy constructor and/or assignment
operator (the heavy stuff but need to revisit) but I'm curious to see
an implementation of the assignment operator that'll compare two
buffers and a copy constructor that'll do just that. Copy an new
object based on exisitng.

The code


// template.h
enum BOOLEAN { FALSE = 0,
TRUE};

template <class T>
class BUFFER
{
public:

BUFFER();
~BUFFER();
void Store(unsigned char const* buffer);
BOOLEAN Retrieve(T& data);
// T Retrieve(T& data); would this be more prudent ??
int Elements_Stored() const;
int Elements_Retrieved() const;

private:

static const int SIZE = 2;
T msg [ SIZE ];

unsigned int store_count;
unsigned int store_index;
unsigned int retrieve_count;

// override compiler defaults
BUFFER(BUFFER<T>& buffer); // Copy construtor.
void operator= (BUFFER<T>& rhs); // Assignment operator


};

// Constructor
template<class T>
BUFFER<T>::BUFFER()
: store_count(0), retrieve_count(0), store_index(1)
{
memset( msg, 0, SIZE * sizeof(T));
}

// Destructor
template<class T>
BUFFER<T>::~BUFFER()
{
}

// store two items. the current and the previous
template<class T>
void BUFFER<T>::Store( unsigned char const* buffer)
{
store_index ^= 1;
// supposidely memcpy is bad news but std::copy benchmarked is slow
// when compared to memcpy
memcpy( &msg[store_index], buffer, sizeof(T));
store_count++; // increment the message stored count
}

// retrieve the most CURRENT item at ALL times
template<class T>
BOOLEAN BUFFER<T>::Retrieve(T& data)
{
if (store_count > 0) // here only to ensure the Retrieve never
// gets called the VERY FIRST TIME before the
Store
{
memcpy( &data, &msg[store_index], sizeof(T));
retrieve_count++;
return TRUE;
}
else
{
return FALSE;
}
}

// returns number of elements stored.
template<class T>
int BUFFER<T>::Elements_Stored() const
{
return store_count;
}

// returns number of elements retrieved.
template<class T>
int BUFFER<T>::Elements_Retrieved() const
{
return retrieve_count;
}


// template.cpp file

#define MAX_MSG_SIZE 4 // avoid preprocessor macro in a ++
environment

enum BOGUS_MSG { msg1Msg,
msg2Msg };

// For simplicity make bit fields 8 deep
struct MSG1
{
unsigned int jdx1 : 8;
unsigned int jdx2 : 8;
unsigned int jdx3 : 8;
unsigned int jdx4 : 8;
};

struct MSG2
{
unsigned int idx1 : 8;
unsigned int idx2 : 8;
unsigned int idx3 : 8;
unsigned int idx4 : 8;
};


int main ( void )
{

BOGUS_MSG msgType;
MSG1 localMsg;
BOOLEAN success;

// Done once at initilization.
BUFFER<MSG1> msg1;
BUFFER<MSG2> msg2;

unsigned char buffer [ MAX_MSG_SIZE ] = { 12, 1, 15, 5 };
memset(&localMsg, 0, sizeof(MSG1)); // no real reason since
// I'll overwrite
localMsg

std::cout << " ----- Before call to Store and Retrieve ---- "
<< std::endl;
std::cout << "MSG1 - jdx1 = " << localMsg.jdx1 << std::endl;
std::cout << "MSG1 - jdx2 = "<< localMsg.jdx2 << std::endl;
std::cout << "MSG1 - jdx3 = " << localMsg.jdx3 << std::endl;
std::cout << "MSG1 - jdx4 = " << localMsg.jdx4 << std::endl;

msgType = msg1Msg;

switch ( msgType )
{
case msg1Msg:
msg1.Store ( buffer );
break;
case msg2Msg:
msg2.Store ( buffer );
break;
default:
std::cout << " bad msg " << std::endl;
break;
}

// later lets Retrieve a message
success = msg1.Retrieve(localMsg); // retrieve the message
if ( success )
{
std::cout << " ----- After call to Store and Retrieve ---- "
<< std::endl;
std::cout << "MSG1 - jdx1 = " << localMsg.jdx1 << std::endl;
std::cout << "MSG1 - jdx2 = "<< localMsg.jdx2 << std::endl;
std::cout << "MSG1 - jdx3 = " << localMsg.jdx3 << std::endl;
std::cout << "MSG1 - jdx4 = " << localMsg.jdx4 << std::endl;
}

// Call msg1.Store message a couple times
// Call msg2.Store
msg1.Store ( buffer );
msg1.Store ( buffer );
msg2.Store ( buffer );

// Print out the index of how many times msg1(should equate to 3)
stored
// Print out the index of how many times msg1(should equate to 1)
stored
std::cout << " --------------------------------------------- "
<< std::endl;
std::cout << "Times called -- MSG1: "
<< msg1.Elements_Stored()
<< std::endl;

std::cout << " --------------------------------------------- "
<< std::endl;
std::cout << "Times called -- MSG2: "
<< msg2.Elements_Stored()
<< std::endl;
std::cout << " --------------------------------------------- "
<< std::endl;

return EXIT_SUCCESS;
}//// end


I'll modify said code to move into the container realm later.

Thanks in advance
  #2  
Old July 19th, 2005, 08:40 PM
Davlet Panech
Guest
 
Posts: n/a
Default Re: implementation details


"forums_mp" <forums_mp@hotmail.com> wrote in message
news:ee300167.0310250833.54e56a8e@posting.google.c om...[color=blue]
> After reading a few texts - nameley koeing/moo and eckel - I decided
> to investigating the importance of templates. Of course there's no
> substitute for practice so I figured I try a simple program.
>
> That said I'm interested in suggestions for improvement on the
> template class (be gracious i'm slowly coming up to speed in ++ :))
> but more importantly I have a few questions.
> For starters, in an ideal world each call to Store should be followed
> by a subsequent Retrieve. If however, Store was called twice before a
> Retrieve then I'd like to implement some sort of overrun check. I
> suspect this could be handled with an overrun_count that'll get
> incremented in Store and decremented in Retrieve or (implementation
> help here)???
>
> Conceptually I understand teh copy constructor and/or assignment
> operator (the heavy stuff but need to revisit) but I'm curious to see
> an implementation of the assignment operator that'll compare two
> buffers and a copy constructor that'll do just that. Copy an new
> object based on exisitng.
>
> The code[/color]

Perhaps you should state what your buffer class is supposed to do. As far as
I can tell it's trying to convert objects of arbitrary types to char arrays.
This will only work for POD types (ints, pointers, structs w/o virtual
members, constructors, etc.). Why don't you try to implement a class that
actually makes sense and is a bit more useful, like a stack of a fixed size.

Anyway, some observations:
- "template.h" is too vague a file name. ".h" is usually used with C
headers. I suggest <ClassName>.hpp instead.
- There is a perfectly good boolean type in C++ already (bool/true/false).
- Since your destructor doesn't do anything, you don't have to declare and
define it.
- Copy ctor takes its argument by *const reference*.
- Assignment operator takes its argument by *const reference* and returns a
*non-const reference" to current object ("return *this;").
- I don't think you need a copy ctor and assignment op in your class at all.
Although I'm not 100% sure as it's a little hard to understand what you are
trying to accomplish. If you don't have members that require explicit
allocation/deallocation, you usually don't need to write copy functions or
the destructor.

D.


  #3  
Old July 19th, 2005, 08:40 PM
forums_mp
Guest
 
Posts: n/a
Default Re: implementation details

>[color=blue]
> Perhaps you should state what your buffer class is supposed to do. As far as
> I can tell it's trying to convert objects of arbitrary types to char arrays.
> This will only work for POD types (ints, pointers, structs w/o virtual
> members, constructors, etc.). Why don't you try to implement a class that
> actually makes sense and is a bit more useful, like a stack of a fixed size.[/color]

Makes 'sense' in what respect? In that regard I'm curious to see how
a stack of a fixed size will be oso differnt when compared to the
simple implementation which I assumed you've 'looked' at. Of course,
realize i'm new to this but in the end all i'm trying to do is
implement a store function that when called will store the most
current and previous message ( a buffer two deep). A retrieve
fucntion when called will return the latest.
[color=blue]
>
> Anyway, some observations:
> - "template.h" is too vague a file name. ".h" is usually used with C
> headers. I suggest <ClassName>.hpp instead.[/color]
I've seen this 'hpp' bit but i'll investigate what that's all about.
In essense, whats the net gain. Is this some new form of 'header'?
[color=blue]
> - There is a perfectly good boolean type in C++ already (bool/true/false).
> - Since your destructor doesn't do anything, you don't have to declare and
> define it.[/color]
agreed on two counts.[color=blue]
> - Copy ctor takes its argument by *const reference*.[/color]
Yikes, missing the const[color=blue]
> - Assignment operator takes its argument by *const reference* and returns a
> *non-const reference" to current object ("return *this;").[/color]
ditto[color=blue]
> - I don't think you need a copy ctor and assignment op in your class at all.
> Although I'm not 100% sure as it's a little hard to understand what you are
> trying to accomplish. If you don't have members that require explicit
> allocation/deallocation, you usually don't need to write copy functions or
> the destructor.[/color]
and I dont require explicit alloc/dealloc. got it!! in light of the
copy cstructor i thought well if I had.

BUFFER<MSG1 > b2;

// later
BUFFER<MSG1 > b3 = b2; // cpystructor would come in handy here?[color=blue]
> D.[/color]
  #4  
Old July 19th, 2005, 08:40 PM
Davlet Panech
Guest
 
Posts: n/a
Default Re: implementation details


"forums_mp" <forums_mp@hotmail.com> wrote in message
news:ee300167.0310260700.3168483b@posting.google.c om...[color=blue][color=green]
> >
> > Perhaps you should state what your buffer class is supposed to do. As[/color][/color]
far as[color=blue][color=green]
> > I can tell it's trying to convert objects of arbitrary types to char[/color][/color]
arrays.[color=blue][color=green]
> > This will only work for POD types (ints, pointers, structs w/o virtual
> > members, constructors, etc.). Why don't you try to implement a class[/color][/color]
that[color=blue][color=green]
> > actually makes sense and is a bit more useful, like a stack of a fixed[/color][/color]
size.[color=blue]
>
> Makes 'sense' in what respect? In that regard I'm curious to see how
> a stack of a fixed size will be oso differnt when compared to the
> simple implementation which I assumed you've 'looked' at. Of course,
> realize i'm new to this but in the end all i'm trying to do is
> implement a store function that when called will store the most
> current and previous message ( a buffer two deep). A retrieve
> fucntion when called will return the latest.[/color]

What I'm saying is you can't do "byte copying" (memcpy(), or equivalent)
with most classes. You should use assignment or copy constrution instead,
instead of "memcpy (&array[index], &a, sizeof (a))", do "array[index] = a".
[color=blue]
>[color=green]
> >
> > Anyway, some observations:
> > - "template.h" is too vague a file name. ".h" is usually used with C
> > headers. I suggest <ClassName>.hpp instead.[/color]
> I've seen this 'hpp' bit but i'll investigate what that's all about.
> In essense, whats the net gain. Is this some new form of 'header'?[/color]

It's just a common convention; compilers don't care about file names.
[color=blue][color=green]
> > - I don't think you need a copy ctor and assignment op in your class at[/color][/color]
all.[color=blue][color=green]
> > Although I'm not 100% sure as it's a little hard to understand what you[/color][/color]
are[color=blue][color=green]
> > trying to accomplish. If you don't have members that require explicit
> > allocation/deallocation, you usually don't need to write copy functions[/color][/color]
or[color=blue][color=green]
> > the destructor.[/color]
> and I dont require explicit alloc/dealloc. got it!! in light of the
> copy cstructor i thought well if I had.
>
> BUFFER<MSG1 > b2;
>
> // later
> BUFFER<MSG1 > b3 = b2; // cpystructor would come in handy here?[/color]

If you don't write a copy ctor/assignment, the compiler will generate one
that copies every member of the source object to the corresponding members
of the destination object. This is good enough for your case.

In other words,
BUFFER<MSG1 > b3 = b2;
will do what you expect even if you don't write copy functions yourself.

D.


 

Bookmarks

Thread Tools

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

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

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles