2013-07-18 2 views
0

В один прекрасный день я решил создать класс в C++ с возможностями хранения, подобными возможностям хранения NSMutableArray в объекте c (я знаю, что векторы - это тип данных goto для такого рода вещей, но я все равно сделал свой собственный). Поэтому я сделал класс mutableArray в C++, и до сих пор он отлично работает. Я могу добавлять и удалять объекты, вставлять их в определенный индекс, если хочу, без указания размера моего массива.C++ изменяемый массив различных типов данных?

Так что моя проблема: до сих пор она может хранить объекты типа int. Есть ли способ сделать это, чтобы он сохранял другие типы данных без необходимости создания целого нового класса для этого конкретного типа? Я не заинтересован в том, чтобы хранить объекты разных типов данных в одном и том же mutableArray, я просто хочу указать, какой тип данных имеет мой mutableArray.

Мой заголовочный файл:

#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 

мой каст файл:

#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; 
} 

Так оно и есть. Любая помощь будет высоко ценится.

+1

Да, это шаблон (например, 'std :: vector', который вы упомянули). Предупреждение: код шаблона не может быть разделен на файлы .h/.cpp, такие как не-шаблонный код. Таким образом, вам придется либо переместить код в .cpp обратно в .h, либо включить .cpp в .h (внизу). Вы не нарушите ODR (одно правило определения), потому что шаблоны являются локальными для TU (единица перевода). Вы можете легко найти дополнительную информацию об этом на SO. – Borgleader

+0

Вы хотите, чтобы один экземпляр массива мог хранить объекты разных типов? – juanchopanza

ответ

2

Это ответит на ваш вопрос

class template

вот пример того, как я реализовал часть вектора класса с помощью шаблона

Это один файл 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 

Это еще один файл с использованием моего класса vetcor

#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; 
} 

Так, как я создал Vector<int> в основном аналогичным образом, просто написав Vector<char>, у вас будет вектор символов. Примечание: файлы заголовков никогда не компилируются

Смежные вопросы