2013-07-18 2 views
0

언젠가 C 언어로 NSMutableArray와 비슷한 저장 용량을 가진 클래스를 생성하기로 결정했습니다. (벡터는 이런 종류의 goto 데이터 타입이지만 어쨌든 내 자신을 만들었습니다.) 그래서 C++에서 mutableArray 클래스를 만들었고, 지금까지는 훌륭하게 작동합니다. 원하는 경우 객체를 추가 및 제거하고 특정 인덱스에 삽입 할 수 있습니다. 배열의 크기를 지정하지 않고도 가능합니다.다양한 데이터 유형의 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 

내 CPP 파일 : 그래서 거기가

#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로 다시 이동 시키거나 .ht (하단)에 .cpp를 포함시켜야합니다. 템플릿은 TU (번역 단위)에 로컬이기 때문에 ODR (하나의 정의 규칙)을 위반하지 않습니다. 이에 대한 자세한 정보는 쉽게 찾을 수 있습니다. – Borgleader

+0

하나의 배열 인스턴스가 다른 유형의 객체를 저장할 수 있도록 하시겠습니까? – juanchopanza

답변

2

여기

class template

내가이

#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 
vector.h 하나 개의 파일입니다 템플릿

를 사용하여 벡터 클래스의 일부를 구현하는 방법의 예입니다 귀하의 질문에 응답 할 것이다

이것은 내 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>을 만든 방법은 문자 벡터를 갖게됩니다. 참고 : 헤더 파일은 컴파일되지 않습니다.