// CArray.h
#ifndef __CARRAY_H__
#define __CARRAY_H__
#include <mem.h>
template <class T>
class CArray
{
public:
// (default) constructor
CArray(int ArraySize=1)
{
// make sure that array is bigger than 0
if(ArraySize < 1)
throw "Error: Invalid Array Size";
// set array size to desired size
Size = ArraySize;
//
Data = new T[Size];
}
// copy constructor
CArray(CArray<T>& CopyArray)
{
// delete data
delete[] Data;
// set to null, just to be safe
Data = NULL;
// get the new array size
Size = CopyArray.Elements();
// reallocate memory for array
Data = new T[Size];
// copy the data
memcpy(Data, NewArray, Memory());
}
~CArray()
{
// Delete the data
delete[] Data;
// set to null, to be safe
Data = NULL;
// no more array, so size is zippo
Size = 0;
}
T& operator[](int Index) const
{
if(Index < 0 || Index >= Size)
{
throw "Error: CArray bounds exceeded";
}
return Data[Index];
}
operator T*() const
{
return(Data);
}
CArray<T>& operator=(const CArray<T>& CopyArray)
{
// delete data
delete[] Data;
// set to null, just to be safe
Data = NULL;
// get the new array size
Size = CopyArray.Elements();
// reallocate memory for array
Data = new T[Size];
// copy the data
memcpy(Data, CopyArray, Memory());
// return this array
return(*this);
}
int Elements() const
{
return(Size);
}
int Memory() const
{
return(Size * sizeof(T));
}
protected:
T* Data;
int Size;
};
#endif
Array Templates
In responce to a post I saw somewhere else on the fourm, one of the posters said that having an array template is something not to be underestimated.
So, a quick trip to my C++ For Dummies (man.. I should get a better C++ book) book finds me in the Template section, with an Array example.
So, copy, play with, add a few things later, I have this:
Well, I''m a little underwhelmed. As far as I (a very novice C++ person) can see, it seems to be a wrapper arround new/delete.
Am I missing something (which I am most likeley)? Other than the new/delete convinience, is there any other benefit, or other function that should be included?
I am NOT saying that this is worthless (I''m working on a string class as well, derived from this, and I think I''m starting to see how it''s benificial), however, I would just like someone who is more informed to fill me in.
Thanks
To all of those who think I''m just being contradictory:
No I''m not!
My First Game!!!"
quote:Well, I'm a little underwhelmed. As far as I (a very novice C++ person) can see, it seems to be a wrapper arround new/delete.
Not really, it's more like a wrapper around an array. Array templates include all the functionality you'd want out of a built-in array, yet they work for any type. A wrapper around new/delete would be your own memory manager, or you own overloaded versions of those operators.
quote:Am I missing something (which I am most likeley)? Other than the new/delete convinience, is there any other benefit, or other function that should be included?
The biggest benefit is that you write the code once, and use it again for any type. The most accurate word to describe it is indeed "container," because it can contain any type. Another advantage is that you can include logic to have the array increase or decrease, without leaving that menial work up to the person using your object.
Array templates aren't too overwhelming, it's just that you need to be familiar with how templates work and getting the array behavior your want. The hardest part would probably be expanding the array, but even that isn't too difficult. Array templates are definitely a good exercise for beginners to put templates to use.
EDIT: At this time I thought I should point out the
vector
and string
classes that are included in the standard library. They are already-implemented array and string objects respectively. Of course, writing your own is a good learning experience, and should be a lot of fun (if you really like programming!)[edited by - Zipster on April 20, 2003 1:48:42 AM]
Ok, I''ll rail your code:
Throw a standard exception instead of char*''s, e.g. std::logic_error
An array size of 0 is well-defined, new T[0] is well-defined.
CArray(CArray& CopyArray)
is wrong
CArray(const CArray& CopyArray)
Your copy-ctor is not exception safe
You array class does not have value semantics (it is not default constructable)
T& operator[](int Index) const
has the wrong semantics
const T& operator[](int Index) const
T& operator[](int Index)
operator T*() const
has the wrong semantics, and should probably be made into an explicit function call
operator const T*() const
operator T*()
- or -
const T* ptr()const;
T* ptr();
Your assignment operator is not exception safe and dies if the same array is assigned to itself.
That''s why writing an array template is not trivial.
Throw a standard exception instead of char*''s, e.g. std::logic_error
An array size of 0 is well-defined, new T[0] is well-defined.
CArray(CArray& CopyArray)
is wrong
CArray(const CArray& CopyArray)
Your copy-ctor is not exception safe
You array class does not have value semantics (it is not default constructable)
T& operator[](int Index) const
has the wrong semantics
const T& operator[](int Index) const
T& operator[](int Index)
operator T*() const
has the wrong semantics, and should probably be made into an explicit function call
operator const T*() const
operator T*()
- or -
const T* ptr()const;
T* ptr();
Your assignment operator is not exception safe and dies if the same array is assigned to itself.
That''s why writing an array template is not trivial.
Yikes, you forgot to insult his mother! I wouldn''t call a templated array non-trivial, but I guess you just have to know what you''re doing before you start.
Another reason why to use
Another reason why to use
vector
.
OK... I think a clarification is in order here.
I did not mean WRITING it was trivial (heck, I never claimed it to be trivial in the first place)--I figured it was more than it looked, and thats why I came here, to find out what the big deal is with them, and why you'd use it over
var_type VarName[Howevertheheckmanyyouwant];
That's ultimately my question.
By the way, I'm still claming to be very novice, so don't rail against my code like I claimed that I'm some |337 h4x0r or something , although I did expect someone was going to take a sledgehammer to it.
*whines*But I LIKE my char*'s
OK, fine, but I don't have much expirience with the std stuff, so I'll do that once I'm done with this class.
Really? Didn't know that one.
(man... really really need a better C++ book)
But what the heck does it do then... or are you gonna go make me look ?
Grr... I remembered that for everything else that mattered for... can't believe I forgot that one.
But it is, thats what the default argument is there for
Ok ok, I'll fix it. I guess assume the want an array size 1 then?
Heh, guess you want me to fall on one side of the fence or the other, right
I guess you mean one or the other (of the bottom two)? I guess I can see how it would be able to tell which to use if I did both--compiler'd have to figure it out based on the call's use, right?
Same deal here, however, my goal is to make it look and act like a REAL array, so an extra function is out of the question here.
Egad. Thanks for pointing that out. And the exception safe thing... that would be catching new/delete messing up?
OK I guess that covers it.
Thanks for the responces, any more would be welcome.
Guess I should virtual the destructor too before someone yells at me for that as well
Edit: OK, apparently we don't like CAPITAL quotes...
To all of those who think I'm just being contradictory:
No I'm not!
My First Game!!!"
[edited by - ElNoNombreHombre on April 20, 2003 12:18:51 PM]
[edited by - ElNoNombreHombre on April 20, 2003 12:19:30 PM]
I did not mean WRITING it was trivial (heck, I never claimed it to be trivial in the first place)--I figured it was more than it looked, and thats why I came here, to find out what the big deal is with them, and why you'd use it over
var_type VarName[Howevertheheckmanyyouwant];
That's ultimately my question.
By the way, I'm still claming to be very novice, so don't rail against my code like I claimed that I'm some |337 h4x0r or something , although I did expect someone was going to take a sledgehammer to it.
quote:
Throw a standard exception instead of char*'s, e.g. std::logic_error
*whines*But I LIKE my char*'s
OK, fine, but I don't have much expirience with the std stuff, so I'll do that once I'm done with this class.
quote:
An array size of 0 is well-defined, new T[0] is well-defined.
Really? Didn't know that one.
(man... really really need a better C++ book)
But what the heck does it do then... or are you gonna go make me look ?
quote:
CArray(CArray& CopyArray)
is wrong
CArray(const CArray& CopyArray)
Grr... I remembered that for everything else that mattered for... can't believe I forgot that one.
quote:
You array class does not have value semantics (it is not default constructable)
But it is, thats what the default argument is there for
Ok ok, I'll fix it. I guess assume the want an array size 1 then?
quote:
T& operator[](int Index) const
has the wrong semantics
const T& operator[](int Index) const
T& operator[](int Index)
Heh, guess you want me to fall on one side of the fence or the other, right
I guess you mean one or the other (of the bottom two)? I guess I can see how it would be able to tell which to use if I did both--compiler'd have to figure it out based on the call's use, right?
quote:
operator T*() const
has the wrong semantics, and should probably be made into an explicit function call
operator const T*() const
operator T*()
- or -
const T* ptr()const;
T* ptr();
Same deal here, however, my goal is to make it look and act like a REAL array, so an extra function is out of the question here.
quote:
Your copy-ctor is not exception safe
---
Your assignment operator is not exception safe and dies if the same array is assigned to itself.
Egad. Thanks for pointing that out. And the exception safe thing... that would be catching new/delete messing up?
OK I guess that covers it.
Thanks for the responces, any more would be welcome.
Guess I should virtual the destructor too before someone yells at me for that as well
Edit: OK, apparently we don't like CAPITAL quotes...
To all of those who think I'm just being contradictory:
No I'm not!
My First Game!!!"
[edited by - ElNoNombreHombre on April 20, 2003 12:18:51 PM]
[edited by - ElNoNombreHombre on April 20, 2003 12:19:30 PM]
You could look into std::vector<>, which allows you to grow & shrink the array at runtime.
Anyway, all that code in the array template? Isn''t it nicer to have to write and debug it only once, instead of having to put all that code into each place in your program where you do those operations?
Anyway, all that code in the array template? Isn''t it nicer to have to write and debug it only once, instead of having to put all that code into each place in your program where you do those operations?
If it''s just a wrapper, there may not be much point. However, consider something like the standard library vector class - it''s like an array, yet it can be resized, grow on demand, used with or without bounds checking, and it works with all the standard library algorithms.
Of course, even just a plain wrapper may be nicer than a raw array - conventional copy semantics, for instance, and at least you can query it for its size ...
Of course, even just a plain wrapper may be nicer than a raw array - conventional copy semantics, for instance, and at least you can query it for its size ...
To the AP, yes, yes I could.
Except I'd like to take a crack at it first
[edited by - ElNoNombreHombre on April 20, 2003 12:21:24 PM]
Except I'd like to take a crack at it first
[edited by - ElNoNombreHombre on April 20, 2003 12:21:24 PM]
quote:
...my goal is to make it look and act like a REAL array, so an extra function is out of the question here.
Well, it''s not an array, so you should only try to immitate it to a reasonable extent. By giving access to internal data, it is possible to modify it without CArray knowing about it, which could, and probably will, be a problem.
quote:
And the exception safe thing... that would be catching new/delete messing up?
That depends. The main issue is that you don''t know the behaviour of T. It could throw when assigning for example. In your copy constructor, Data is deleted first. If any other operation after that throws, it will not be possible to recover it. Exception safety menas giving a guarantee that CArray is at least destroyable (don''t leak or crash) if an exception is thrown. You can widen the guarantee so that an exception will not affect you array at all. It''s a tricky business, writing exception safe code, at least in my opininon.
quote:
Guess I should virtual the destructor too before someone yells at me for that as well
Not necessarily. That is up to you. It''s more likely that you will use delegation instead of inheritance, when reusing the array.
Regards Mats
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement