2018年11月16日 星期五

c++ 實作一個 stack array 可以 push 及 pop

//stack.cc
#include <stdio.h>
#include <stdarg.h>
#include <typeinfo>
template <typename anyType>
struct myArray{
    anyType *array;
    int  length; // 32-bits length is huge enough
    myArray()                {
        if( typeid(anyType) != typeid(int) && typeid(anyType) != typeid(double) ) printf("va_arg(args, type) must be int or double for type\n");       
        array=NULL;
        length =0;   
     }
    ~myArray()               { if( ! array ) delete array; }
    template <typename... anyList>
    myArray* push(anyList... parameters) { __push(sizeof...(parameters), parameters...); }   
    myArray* __push(int argc, ...)       {
        anyType* newptr = new anyType[length + argc]; // new array need more space for parameters
        if( array != NULL ) { // array copy to a new array first
            for(int i = 0; i < length; i++) newptr[i] = array[i];
            delete array; // free useless array
        }
        va_list args;
        va_start(args, argc);      
        while (argc-- > 0) newptr[length++]=va_arg(args, anyType);// add element to tail one by one
        va_end(args);
        array = newptr; // point to new array
        return this;    // method chain if necessary
     }
    anyType pop(){
        if(  length>0 ) length--;  // decrease one element
        return          array[length];  // pop element from last one
     }   
    myArray* printf(const char *fmt, ...){ // avoid waring for incorrect type
        va_list args;
        va_start(args, fmt);
        vprintf(fmt, args);
        va_end(args);
        return this; // method chain if necessary
     }   
    myArray* listall(bool eol = true) { // default End Of Line is true
        for (int i = 0;i < length; i++) {
            if( typeid(anyType) == typeid(int)  )                   printf("%d",array[i]);
            else if( typeid(anyType) == typeid(double)  )  printf("%f",array[i]);               
            if( i < length-1 ) printf(", "); // if not last one, add comma and space
        }
        if (eol) printf("\n"); // default print EOL
        return this; // method chain if necessary
     }
 };
int main(void){
    auto cc = new myArray
<double>;
    cc->push(1.0, 2.0)->push(3.0, 4.0)->push(5.0)->push(6.0, 7.0, 8.0)->listall();
    printf("pop %f\n", cc->pop());
    cc->listall();
}

編譯程式並執行 g++  stack.c   &&  ./a.out
1.000000, 2.000000, 3.000000, 4.000000, 5.000000, 6.000000, 7.000000, 8.000000
pop 8.000000
1.000000, 2.000000, 3.000000, 4.000000, 5.000000, 6.000000, 7.000000
 

沒有留言: