在编译时使用类型未知的对象初始化

Class with an object of type unknown at the compilation time

本文关键字:未知 对象 初始化 类型 编译      更新时间:2023-10-16

我确信这个问题在这里被提及过很多次,但我真的找不到我所遇到的问题类型的答案。我有一个类,它需要在内部保存一个数组。但是该数组的类型是可靠的(确切地说,它取决于打开的wave文件的比特率,例如8位-char、16位-short等)。我需要在其中一个类方法中定义它。

我的想法是使用auto关键字来声明指针:

class WaveReader {
//
auto *data;
};

然后,在方法内部:

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

但那是个愚蠢的主意。我知道最简单的方法是为每种类型声明数组,但我想知道是否有一种聪明的方法,也许可以使用一些模板?非常感谢你的帮助。

auto关键字不是为此而设计的,请将数据声明为:

void* data;

然后,您可以只使用int或enum来跟踪数据的类型。如

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

并修改您的代码如下:

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 )
{
    ...
}

您可能需要思考"这意味着什么"。是的,在某些情况下,这种类型的事情(例如通过jsidhu解决)正是您想要和需要的。但很多时候,这表明你试图做一些"不太正确的方式"的事情。

一种替代方案是使用虚拟功能:

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(); 
}

多种数据类型。您可以使用相同的名称创建单独的重载函数。根据传递的数据类型,它将使用正确的函数。然后,函数可以从中用调用正确的类。

我会使用联合来处理作业:

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;

由于您只存储POD,所以如果您分配N*2个char s或N个short s,并且您可以在不强制转换的情况下使用正确的指针类型,这并不重要。

另外:<inttypes.h>中的整数类型,因为"基本"整数类型的绝对大小没有限制。