Sign in to follow this  

Which Method is best

This topic is 4336 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Which of these two would be the best implementation. Arrays without inheritance
#ifndef ARRAYS_H
#define ARRAYS_H
#ifdef WIN32
#pragma once
#pragma comment(lib, "nothrownew.obj")
#endif

template < class T > class Array
{
private:
	T *m_pArray;
	int m_Size;

public:
	Array(int Size)
	{
		this->m_pArray = new T[Size];
		if (this->m_pArray == NULL)
			this->m_Size = 0;
		else
			this->m_Size = Size;
	}

	~Array()
	{
		if (this->m_pArray != NULL)
		{
			delete [] this->m_pArray;
			this->m_Size = 0;
			this->m_pArray = NULL;
		}
	}

	bool Resize(int Size)
	{
		T *newArray = new T[Size];
		if (newArray == NULL)
			return false;

		int min = (Size < this->m_Size) ? Size : this->m_Size;
		this->m_Size = Size;

		for (int i = 0; i < min; i++)
			newArray[i] = this->m_pArray[i];

		if (this->m_pArray != NULL)
			delete [] this->m_pArray;

		this->m_pArray = newArray;
		newArray = NULL;

		return true;
	}

	bool IsValid()
	{
		return (this->m_pArray != NULL);
	}

	T& operator[](int Index)
	{
		return this->m_pArray[Index];
	}

	int Size()
	{
		return this->m_Size;
	}
};

template < class T > class Array2d
{
private:
	T *m_pArray;
	int m_Width;
	int m_Height;

public:
	Array2d(int Width, int Height)
	{
		this->m_pArray = new T[Width * Height];
		if (this->m_pArray == NULL)
		{
			this->m_Width = 0;
			this->m_Height = 0;
		}
		else
		{
			this->m_Width = Width;
			this->m_Height = Height;
		}
	}

	~Array2d()
	{
		if (this->m_pArray != NULL)
		{
			delete [] this->m_pArray;
			this->m_Width = 0;
			this->m_Height = 0;
			this->m_pArray = NULL;
		}
	}

	bool Resize(int Width, int Height)
	{
		T *newArray = new T[Width * Height];
		if (newArray == NULL)
			return false;

		int minWidth = (Width < this->m_Width) ? Width : this->m_Width;
		int minHeight = (Height < this->m_Height) ? Height : this->m_Height;
		this->m_Width = Width;
		this->m_Height = Height;

		int offset1 = 0;
		int offset2 = 0;
		for (int y = 0; y < minHeight; y++)
		{
			offset1 = y * minWidth;
			offset2 = y * this->m_Width;
			for (int x = 0; x < minWidth; x++)
				newArray[offset1 + x] = this->m_pArray[offset2 + x];
		}

		if (this->m_pArray != NULL)
			delete [] this->m_pArray;

		this->m_pArray = newArray;
		newArray = NULL;

		return true;
	}

	bool IsValid()
	{
		return (this->m_pArray != NULL);
	}

	T& Index(int x, int y)
	{
		return this->m_pArray[y * this->m_Width + x];
	}

	int Width()
	{
		return this->m_Width;
	}

	int Height()
	{
		return this->m_Height;
	}

	int Size()
	{
		return this->m_Width * this->m_Height;
	}
};

template < class T > class Array3d
{
private:
	T *m_pArray;
	int m_Width;
	int m_Height;
	int m_Depth;

public:
	Array3d(int Width, int Height, int Depth)
	{
		this->m_pArray = new T[Width * Height * Depth];
		if (this->m_pArray == NULL)
		{
			this->m_Width = 0;
			this->m_Height = 0;
			this->m_Depth = 0;
		}
		else
		{
			this->m_Width = Width;
			this->m_Height = Height;
			this->m_Depth = Depth;
		}
	}

	~Array3d()
	{
		if (this->m_pArray != NULL)
		{
			delete [] this->m_pArray;
			this->m_Width = 0;
			this->m_Height = 0;
			this->m_Depth = 0;
			this->m_pArray = NULL;
		}
	}

	bool Resize(int Width, int Height, int Depth)
	{
		T *newArray = new T[Width * Height * Depth];
		if (newArray == NULL)
			return false;

		int minWidth = (Width < this->m_Width) ? Width : this->m_Width;
		int minHeight = (Height < this->m_Height) ? Height : this->m_Height;
		int minDepth = (Depth < this->m_Depth) ? Depth : this->m_Depth;
		this->m_Width = Width;
		this->m_Height = Height;
		this->m_Depth = Depth;

		int offset1 = 0;
		int offset2 = 0;
		int offset3 = 0;
		int offset4 = 0;

		for (int z = 0; z < minDepth; z++)
		{
			offset1 = z * minWidth * minHeight;
			offset3 = z * this->m_Width * this->m_Height;
			for (int y = 0; y < minHeight; y++)
			{
				offset2 = y * minWidth;
				offset4 = y * this->m_Width;
				for (int x = 0; x < minWidth; x++)
					newArray[offset1 + offset2 + x] = this->m_pArray[offset3 + offset4 + x];
			}
		}

		if (this->m_pArray != NULL)
			delete [] this->m_pArray;

		this->m_pArray = newArray;
		newArray = NULL;

		return true;
	}

	T& Index(int x, int y, int z)
	{
		return this->m_pArray[(z * this->m_Width * this->m_Height) + (y * this->m_Width) + x];
	}

	int Width()
	{
		return this->m_Width;
	}

	int Height()
	{
		return this->m_Height;
	}

	int Depth()
	{
		return this->m_Depth;
	}

	int Size()
	{
		return this->m_Width * this->m_Height * this->m_Depth;
	}

	bool IsValid()
	{
		return (this->m_pArray != NULL);
	}
};


#endif


Arrays with inheritance
#ifndef ARRAYS_H
#define ARRAYS_H
#ifdef WIN32
#pragma once
#pragma comment(lib, "nothrownew.obj")
#endif

template < class T > class ArrayBase
{
protected:
	T *m_pArray;
	int m_Size;

public:
	ArrayBase(int Size)
	{
		this->m_pArray = new T[Size];
		if (this->m_pArray == NULL)
			this->m_Size = 0;
		else
			this->m_Size = Size;
	}

	~ArrayBase()
	{
		if (this->m_pArray != NULL)
		{
			delete [] this->m_pArray;
			this->m_pArray = NULL;
		}
		this->m_Size = 0;
	}

	bool IsValid()
	{
		return (this->m_pArray != NULL);
	}

	int Size()
	{
		return this->m_Size;
	}
};

template < class T > class Array : public ArrayBase<T>
{
public:
	Array(int Size) : ArrayBase(Size)
	{
	}

	~Array()
	{
	}

	bool Resize(int Size)
	{
		T *newArray = new T[Size];
		if (newArray == NULL)
			return false;

		int min = (Size < ArrayBase::m_Size) ? Size : ArrayBase::m_Size;
		ArrayBase::m_Size = Size;

		for (int i = 0; i < min; i++)
			newArray[i] = ArrayBase::m_pArray[i];

		if (ArrayBase::m_pArray != NULL)
			delete [] ArrayBase::m_pArray;

		ArrayBase::m_pArray = newArray;
		newArray = NULL;

		return true;
	}

	T& operator[](int Index)
	{
		return ArrayBase::m_pArray[Index];
	}
};

template < class T > class Array2d : public ArrayBase<T>
{
private:
	int m_Width;
	int m_Height;

public:
	Array2d(int Width, int Height) : ArrayBase(Width * Height)
	{
		if (ArrayBase::m_pArray == NULL)
		{
			this->m_Width = 0;
			this->m_Height = 0;
		}
		else
		{
			this->m_Width = Width;
			this->m_Height = Height;
		}
	}

	~Array2d()
	{
		this->m_Width = 0;
		this->m_Height = 0;
	}

	bool Resize(int Width, int Height)
	{
		int size = Width * Height;
		T *newArray = new T[size];
		if (newArray == NULL)
			return false;

		int minWidth = (Width < this->m_Width) ? Width : this->m_Width;
		int minHeight = (Height < this->m_Height) ? Height : this->m_Height;
		this->m_Width = Width;
		this->m_Height = Height;
		ArrayBase::m_Size = size;

		int offset1 = 0;
		int offset2 = 0;
		for (int y = 0; y < minHeight; y++)
		{
			offset1 = y * minWidth;
			offset2 = y * this->m_Width;
			for (int x = 0; x < minWidth; x++)
				newArray[offset1 + x] = ArrayBase::m_pArray[offset2 + x];
		}

		if (ArrayBase::m_pArray != NULL)
			delete [] ArrayBase::m_pArray;

		ArrayBase::m_pArray = newArray;
		newArray = NULL;

		return true;
	}

	
	T& Index(int x, int y)
	{
		return ArrayBase::m_pArray[y * this->m_Width + x];
	}

	int Width()
	{
		return this->m_Width;
	}

	int Height()
	{
		return this->m_Height;
	}
};

template < class T > class Array3d : public ArrayBase<T>
{
private:
	int m_Width;
	int m_Height;
	int m_Depth;

public:
	Array3d(int Width, int Height, int Depth) : ArrayBase(Width * Height * Depth)
	{
		if (ArrayBase::m_pArray == NULL)
		{
			this->m_Width = 0;
			this->m_Height = 0;
			this->m_Depth = 0;
		}
		else
		{
			this->m_Width = Width;
			this->m_Height = Height;
			this->m_Depth = Depth;
		}
	}

	~Array3d()
	{
		this->m_Width = 0;
		this->m_Height = 0;
		this->m_Depth = 0;
	}

	bool Resize(int Width, int Height, int Depth)
	{
		int size = Width * Height * Depth;
		T *newArray = new T[size];
		if (newArray == NULL)
			return false;

		int minWidth = (Width < this->m_Width) ? Width : this->m_Width;
		int minHeight = (Height < this->m_Height) ? Height : this->m_Height;
		int minDepth = (Depth < this->m_Depth) ? Depth : this->m_Depth;
		this->m_Width = Width;
		this->m_Height = Height;
		this->m_Depth = Depth;
		ArrayBase::m_Size = size;

		int offset1 = 0;
		int offset2 = 0;
		int offset3 = 0;
		int offset4 = 0;

		for (int z = 0; z < minDepth; z++)
		{
			offset1 = z * minWidth * minHeight;
			offset3 = z * this->m_Width * this->m_Height;
			for (int y = 0; y < minHeight; y++)
			{
				offset2 = y * minWidth;
				offset4 = y * this->m_Width;
				for (int x = 0; x < minWidth; x++)
					newArray[offset1 + offset2 + x] = ArrayBase::m_pArray[offset3 + offset4 + x];
			}
		}

		if (ArrayBase::m_pArray != NULL)
			delete [] ArrayBase::m_pArray;

		ArrayBase::m_pArray = newArray;
		newArray = NULL;

		return true;
	}

	T& Index(int x, int y, int z)
	{
		return this->m_pArray[(z * this->m_Width * this->m_Height) + (y * this->m_Width) + x];
	}

	int Width()
	{
		return this->m_Width;
	}

	int Height()
	{
		return this->m_Height;
	}

	int Depth()
	{
		return this->m_Depth;
	}
};


#endif


[Edited by - Akusei on January 27, 2006 4:14:51 PM]

Share this post


Link to post
Share on other sites
I would go with #1, just personal opinion. You aren't really doing anything with inheritance other than just splitting the code into mutliple classes. Also, if you wanted a 2d array, you can do:

Array<Array<int> > array2d;
(array2d[0])[0] = 2;


You do know that all the big functions are going to be inlined, right?

Share this post


Link to post
Share on other sites
Quote:
Original post by agi_shi
I would go with #1, just personal opinion. You aren't really doing anything with inheritance other than just splitting the code into mutliple classes. Also, if you wanted a 2d array, you can do:

Array<Array<int> > array2d;
(array2d[0])[0] = 2;


You do know that all the big functions are going to be inlined, right?


Yes... Isn't that a requirement of a Templated class, that all the functions need to be inline? Also, is that a bad thing that all the big function will be inlined? Does that mean that every call to that function will be replace with a "copy" of it's actual code?

Share this post


Link to post
Share on other sites
It is incorrect to think of inlining as a bad thing ... unless the compiler does not implement it properly.

What inlining means is that the compiler gets to make the decision to either compile a function for the item, or not. And in fact gets to make this decision per compilation unit (although a compiler worth anything would make the decision on a per-library basis).

If a function is 200 opcodes long, and has more than a single call, the compiler is going to compile it as a function .. reguardless of the theoretical "inlining".

Share this post


Link to post
Share on other sites
Both look perfectly valid, I really think it's a matter of personal preference and maintainability.

That being said, I'd probably go with #2, as it does offer the *slight* advantage over #1 in the fact you could go back and write another class to do more dimensions if you'd like. Why go OO if you don't wanna go OOll the way, know what I mean?

Then again I'm typically an ASM/C programmer, and I only touch the ++ stuff once in a blue moon, so my opinion might be about as valid as the Pope giving instructions on how to become a Baptist.

Share this post


Link to post
Share on other sites
Thanks for the response... The main reason (for me anyway) for having a base class in #2 was that I has an IsValid is every class and a Size function in every class. I did not want to make changes to all the IsValids or Sizes of all the classes. Likewise, I did not want to write IsValid and Size 3 different times.

Forgive me if this makes no sense, I'm really really tired...

Share this post


Link to post
Share on other sites

This topic is 4336 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this