I decided one day to create a class in c++ with storage capabilities similar to that of NSMutableArray in objective c (I know vectors are the goto data type for this sort of thing but I made my own anyway). So I made a mutableArray class in c++, and so far it works great. I can add and remove objects, insert them to a specific index if I want, all without having to specify the size of my array.

So my problem is: so far, it can only store objects of type int. Is there any way I can make it so it holds other datatypes without having to create a whole new class for that specific type? I'm not interested in being able to store objects of different datatypes in the same mutableArray, I just want to be able to specify what datatype my mutableArray holds.

My header file:

#define MUTABLEARRAY_H


class mutableArray
{
    public:
        mutableArray();
        virtual ~mutableArray();
        void initWithSize(int length);
        void initWithArrayThroughIndeces(int nums[], int minimum, int maximum);
        void addObject(int number);
        void insertObjectAtIndex(int number, int index);
        void changeSize(int length);
        void removeLastObject();
        void removeObjectAtIndex(int index);
        int objectAtIndex(int index);
        int lastObject();
        int firstObject();
        int countObjects();
    protected:
    private:
        int *start;
        int amount;
};

#endif // MUTABLEARRAY_H

my cpp file:

#include "mutableArray.h"

mutableArray::mutableArray()
{
    //ctor
    start = new int;
    amount = 0;
}

mutableArray::~mutableArray()
{
    //dtor
}

void mutableArray::initWithSize(int length){
    amount = length;
}

void mutableArray::initWithArrayThroughIndeces(int nums[], int minimum, int maximum){
    amount = maximum - minimum;
    start = nums + minimum;
}

void mutableArray::addObject(int number){
    amount++;
    start[amount] = number;
}

void mutableArray::insertObjectAtIndex(int number, int index){
    amount++;
    int j = 0;
    for (int *i = start + amount; i > start; i--){
        if (j >= index){
            start[j + 1] = *i;
        }
        j++;
    }
    start[index] = number;
}

void mutableArray::removeLastObject(){
    amount--;
}

void mutableArray::removeObjectAtIndex(int index){
    amount--;
    int j = 0;
    for (int *i = start; i < start + amount; i++){
        if (j != index){
            start[j] = *i;
            j++;
        }
    }
}

int mutableArray::objectAtIndex(int index){
    return start[index];
}

int mutableArray::lastObject(){
    return start[amount];
}

int mutableArray::firstObject(){
    return *start;
}

int mutableArray::countObjects(){
    return amount;
}

So there it is. Any help will be much appreciated.

share
1  
Yeah make it a template (like std::vector you mentioned). Warning: Template code cannot be split in .h/.cpp files like non-templated code. So you'll either have to move the code in the .cpp back in to the .h or include the .cpp in the .h (at the bottom). You won't break the ODR (one definition rule) because templates are local to the TU (translation unit). You can easily find more info on this on SO. – Borgleader Jul 18 '13 at 6:13
    
Do you want one single array instance to be able to store objects of different types? – juanchopanza Jul 18 '13 at 8:15

This will answer your question

class template

here is an example of how I implemented a part of vector class using template

This is one file vector.h

#ifndef VECTOR_H
#define VECTOR_H

#include <iostream>
#include<stdlib.h>
#include<malloc.h>



template <typename T> 
class Vector{
private:
    T *buffer;
    int threshold;
    int length;
    void Allocate();
    void ReAllocate(int);

public:


    Vector();
    ~Vector();
    void push_back (const T& val);
    void pop_back();
    void clear(void);
    void erase (int position);
    void erase (int first, int last);
    int  capacity() const;
    int size() const;
    T* at(int n) const;
    T& operator[] (int n) const;

};

template <typename T> 
Vector<T>:: Vector(){
    buffer=NULL;
    length=0;
    threshold=10;
    Allocate();

}

template <typename T> 
void Vector<T>::Allocate(){
    buffer = (T*)(malloc(threshold*sizeof(T)));
}

template <typename T> 
void Vector<T>::ReAllocate(int size_x){
  std::cout<<"In buffer realloc"<<std::endl;
        threshold=threshold+size_x;
    buffer = (T*)(realloc(buffer,(sizeof(T))*threshold));

}

template <typename T> 
void Vector<T>::push_back (const T& val){

     if(length<threshold){
    buffer[length]=val;
    std::cout<<buffer[length]<<std::endl;
    length++;
    }
   else{
       ReAllocate(10);
       push_back(val);
   }
}

template <typename T> 
void Vector<T>::erase (int first, int last){
    T *tempBuffer=buffer;

    if(first>=0&&last<length){
                int count=0;
            for(int i=0;i<length;i++){

                if(i<first||i>last){
                    buffer[count]=buffer[i];
                count++;
                }

        }
        length=count;
    }else{

            // illegal params

              }

}

template <typename T> 
void Vector<T>::erase(int position){


if(position>=0&&position<length){
                int count=0;
            for(int i=0;i<length;i++){

                if(i!=position-1){
                    buffer[count]=buffer[i];
                count++;
                }

        }
        length--;
    }else{

            // illegal params

              }

}



template <typename T> 
Vector<T>:: ~Vector(){
    free(buffer);
    length=0;
    threshold=10;
    Allocate();

}

template <typename T> 
int Vector<T>::capacity() const{

    return threshold;

}

template <typename T> 
int Vector<T>::size() const{

    return length;

}


template <typename T> 
T* Vector<T>::at(int n) const{

    if(n>0&&n<length){

        return &buffer[n];

    }

    else return NULL;
}


template<typename T>
void Vector<T>::clear(void){

    buffer[length]=0;
    length=0;

}


template<typename T>
T& Vector<T>::operator[](int n) const{

if(n>0&&n<length){
return buffer[n];
}

}


#endif

This is another file using my vetcor class

#include"Vector.h"
#include<iostream>



int main(){


Vector<int> vec;

vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);
vec.erase(1);

std::cout<<vec.capacity()<<std::endl;
std::cout<<vec.size()<<std::endl;
int* a=vec.at(2);

std::cout<<"Element At 2 is :"<<*a<<std::endl;
std::cout<<"Element At 2 using [] operator :"<<vec[5]<<std::endl;


return 0;
}

So the way I created Vector<int> in main in the similar manner by just writing Vector<char> you will have vector of characters. Note: header files are never compiled

share

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.