C++ 在编译时使用未知类型的对象初始化
我相信这个问题在这里已经被讨论过很多次了,但是我真的找不到我遇到的问题的答案。我有一个类需要在里面保存一个数组。但是该数组的类型是可靠的(确切地说,它取决于打开的wave文件的比特率,例如8位字符、16位短字符等)。我需要在一个类方法中定义它 我的想法是使用C++ 在编译时使用未知类型的对象初始化,c++,auto,C++,Auto,我相信这个问题在这里已经被讨论过很多次了,但是我真的找不到我遇到的问题的答案。我有一个类需要在里面保存一个数组。但是该数组的类型是可靠的(确切地说,它取决于打开的wave文件的比特率,例如8位字符、16位短字符等)。我需要在一个类方法中定义它 我的想法是使用auto关键字声明指针: class WaveReader { // auto *data; }; 然后,在方法内部: void some_func(int datasize) { // case 8: d
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 )
{
...
}
void some_func(int datasize)
{
//
案例8:
数据=静态_转换(新字符[数据大小]);
数据类型=字符;
打破
案例16:
数据=静态(新短[数据大小]);
数据类型=短;
打破
//
等
}
...
if(数据类型==CHAR)
{
...
}
else if(数据类型==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*2char
s或Nshort
s,并且您可以使用正确的指针类型而无需强制转换,这并不重要
另外:整数类型来自
,因为在“基本”整数类型的绝对大小上没有garantuee。谢谢,我正要问铸造的问题。这就解决了问题。类似这样:delete[]static\u cast(data)
实际上,应该只需要做:delete[]data;delete将计算出其余的。问题是wave文件中的样本是8、16、24位等,当它们是8时,它们是无符号的,其余的是有符号的。当我读取文件时,我需要将样本存储在适当的阵列中,否则它们将无法通过音频库正确播放。您的解决方案看起来不错,但这比仅声明不同类型向量的代码要多10倍。没有简单的方法可以解决这个问题吗?不过Jsidhu解决方案似乎不安全(我会遇到随机崩溃),因此上述解决方案中的原理对于存储音频样本非常有效。很久以前,我在Python中实现了一些非常类似的东西,当我使用Symbian的图形时,上述类型的解决方案用于存储/检索像素。显然,您可能希望在基础中使用一些“通用”功能,并且仅使用派生函数来计算数据的大小,我不认为随机崩溃是因为jsidhu的解决方案本身就不好。它只是没有我的解决方案那么封装,这意味着每当你需要知道“我的数据现在有多大”时,你必须编写大量额外的代码。对不起,崩溃是由我的错误造成的。你是对的,当我思考时,你的解决方案变得越来越有意义。我会牢记在心,看看哪个最适合我。谢谢