声明具有未知类型的变量

时间:2014-04-07 08:27:31

标签: c++

我在c ++程序中读取.wav文件。

.wav格式是样本为uint8_tint16_t。是否可以根据特定文件的格式声明变量?

一种解决方案是:

int16_t sample;
if (bits==8)
{
  uint8_t temp8;
  in.read((char*)&temp8,bits);
  sample = (int16_t) temp8;
}
else
{
  in.read((char*)&sample,bits);
}

从现在开始我可以使用sample。然而,这似乎并不是很方便,在8位情况下,变量sample比需要的更大。

我相信这也可以通过union完成,但它仍会使变量占用2个字节,无论如何。

我真正想要的是:

if(bits==8)
  uint8_t sample;
else
  int16_t sample;

但是范围超出条件陈述。

1 个答案:

答案 0 :(得分:3)

您可以使用抽象基类和模板类来提供示例阅读器的不同实现。使用抽象接口,以后的代码不需要知道它是否处理8位或16位样本。

#include <fstream>
#include <vector>
#include <exception>

class SampleReader
{
public:
    virtual void readSample( std::ifstream &in ) = 0;
};

template<class T>
class SampleReaderT : public SampleReader
{
public:
    virtual void readSample( std::ifstream &in )
    {
        while (!in.eof()) {
            const T value = readOneValue(in);
            if (in) {
                _sample.push_back();
            } else {
                break;
            }
        }
    }

private:
    T readOneValue( std::ifstream &in )
    {
        T inputUnit;
        in.read((char*)&inputUnit,sizeof(T));
    }

private:
    std::vector<T> _sample;
};

typedef SampleReaderT<int8_t> SampleReader8Bit;
typedef SampleReaderT<int16_t> SampleReader16Bit;

int main(int argc, char** argv)
{
    int sampleBits = 8;

    SampleReader *sampleReader = nullptr;
    if (sampleBits == 8) {
        sampleReader = new SampleReader8Bit();
    } else if (sampleBits == 16) {
        sampleReader = new SampleReader16Bit();
    } else {
        throw std::out_of_range("unknown bit number");
    }

    std::ifstream in("test.dat");
    sampleReader->readSample(in);
}

请注意此示例中的以下内容:

  • 这只是一个示例,您当然需要为您的项目找到更好的设计。
  • 有一个带有纯虚方法的基类。这个基类对于使代码抽象是一个很好的帮助。你可以使用指向SampleReader的指针,而不必知道这是一个8位还是16位的样本阅读器。
  • 显示的读取值的方法是非平台无关。有些平台具有不同的字节顺序。
  • 此示例中缺少错误处理。阅读流可能会随时引发错误。