Domanda

i am sure this problem was touched here many times but i really can't find an answer to the type of problem i have. I have a class that needs to hold an array inside. But the type of that array is dependable (to be exact, it depends on what is the bit rate of the opened wave file, for example 8 bit - char, 16 bit - short etc.). I need it to be defined in one of the class method.

My idea was to use the auto keyword to declare the pointer:

class WaveReader {

//

auto *data;

};

and then, inside the method:

void some_func(int datasize)
{
    //
    case 8:
      data = new char[datasize];
      break;
    case 16:
      data = new short[datasize];
      break;
    //
    etc.
}

but that was a stupid idea. I know the easiest way would be to declare arrays for each type but i would like to know if there's a smart way, maybe with some template use? Thanks a lot for any help.

È stato utile?

Soluzione

The auto keyword is not designed for this, declare data as:

void* data;

Then, you can just use an int or enum to keep track of the type of data. Such as,

typedef enum 
{
    CHAR,
    SHORT
} DataTypeEnum;
...
DataTypeEnum dataType;
...

and modify your code as follows:

void some_func(int datasize)
{
    //
    case 8:
      data = static_cast<void*>(new char[datasize]);
      dataType = CHAR;
      break;
    case 16:
      data = static_cast<void*>(new short[datasize]);
      dataType = SHORT;
      break;
    //
    etc.
}
...
if( dataType == CHAR )
{
    ...
}
else if ( dataType == SHORT )
{
    ...
}

Altri suggerimenti

You probably want to think about "what does this mean". Yes, there are situations when this type (solved as by jsidhu, for example) of thing is exactly what you want and need. But quite often it indicates that you are trying to do soemthing "not quite the right way".

One alternative is to use virtual functions:

class Base
{
   public: 
    virtual void do_stuff_with_data() = 0;
}

class CharData
{
  private:
    char * data;

  public:
    CharData(size_t size) { data = new char[size]; }

    void do_stuff_with_data() { ... }; 
};

class ShortData
{
  private:
    short* data;

  public:
    ShortData(size_t size) { data = new short[size]; }
    void do_stuff_with_data() { ... }; 
};

void some_func(int datasize)
{
    Base *pBase;
    case 8:
      pBase = new CharData(datasize);
      break;
    case 16:
      pBase = new ShortData(datasize);
      break;
    //
    etc.

    pBase->do_stuff_with_data(); 
}

Multiple datatypes. You can make separate overloaded functions with the same name. Depending on the type of data passed, it will use the right function. The function can then call the right class from with in.

I would use a union to to the job:

union {
    int8_t *i8;
    int16_t *i16;
    /* ... */
} data;

// snip

switch (bitsPerSample) {
case 8:
     dataType = CHAR;
     break;
case 16:
     dataType = SHORT;
     break;
default:
     // throw
}

data.i8 = new int8_t[datasize * bitsPerSample / CHAR_BIT];

do_8bit(data.i8);
// or
do_16bit(data.i16);

delete[] data.i8;

Since you only store POD, it doesn't matter, if you allocate N*2 chars or N shorts, and you can use the correct pointer type without casting.

Also: Integer types from <inttypes.h> because there is no garantuee on the absolute sizes of "basic" integer types.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top