拥有指向模板基类

时间:2015-08-31 09:13:57

标签: c++ templates polymorphism bitset

在下面的代码中,我有一个名为IDecoder的接口,它应该由任何解码器类(DecoderADecoderB来实现)。 IDecoder中包含bitset<>,因此我将IDecoder设为模板类,并在派生类中确定bitset的大小。我还有一个Container类,它应该指向IDecoder类,但由于IDecoder不是完整类型,我添加了一个虚拟DecoderBase IDecoder继承的类:

#include <iostream>
#include <bitset>

class DecoderBase
{
public:
    DecoderBase(){}
    virtual ~DecoderBase(){}
};

template<size_t nb>
class IDecoder : public DecoderBase
{
public:
    IDecoder(){}
    virtual ~IDecoder(){}
    virtual std::bitset<nb> GetDecodedFields() = 0;
};

const int DecoderAMaxFields = 100;
const int DecoderBMaxFields = 200;

class DecoderA : public IDecoder<DecoderAMaxFields>
{
public:
    DecoderA(){}
    ~DecoderA(){}
    std::bitset<DecoderAMaxFields> GetDecodedFields()
    {
        std::bitset<DecoderAMaxFields> bits;
        // assume we've decoded fileds number 1 and 10 here
        bits[1] = 1;
        bits[10] = 1;
        return bits;
    }
};

class DecoderB : public IDecoder<DecoderBMaxFields>
{
public:
    DecoderB(){}
    ~DecoderB(){}
    std::bitset<DecoderBMaxFields> GetDecodedFields()
    {
        std::bitset<DecoderBMaxFields> bits;
        // assume we've decoded fileds number 11, 29, 110 & 142 here
        bits[11] = 1;
        bits[29] = 1;
        bits[110] = 1;
        bits[142] = 1;
        return bits;
    }
};

class Container
{
public:
    Container(){}
    virtual ~Container(){}
    void SetDecoder(DecoderBase* decoder)
    {
        mDecoder = decoder;
    }
    DecoderBase* GetDecoder()
    {
        return mDecoder;
    }
private:
    DecoderBase* mDecoder;
};

int main()
{
    Container container;
    container.SetDecoder(new DecoderA());
    ((DecoderA*)container.GetDecoder())->GetDecodedFields();
    return 0;
}

正如您所看到的,在调用GetDecodedFields()之前,我必须将其转换为其中一个解码器,这与多态性的目的完全相反!我该如何修复此代码?我还想过使用boost::dynamic_bitset,但我不想使用它,因为它比普通bitset慢。

2 个答案:

答案 0 :(得分:0)

编辑:此答案是对该问题所作评论的补充。

  • Container使用什么样的解码器是运行时信息,而bitset的大小必须在编译时声明。这两个概念不会合作。你应该考虑使用vector。
  • BTW:std :: bitset&lt; 100&gt;的类型。和std :: bitset&lt; 200&gt;是不同的。没有可以用作基类的类型std :: bitset。这不是模板的工作方式。因此DecoderBase无法知道您要返回哪种类型。

在这种情况下如何使用std::vector<bool>代替固定大小std::bitset<N>的示例:

#include <iostream>
#include <bitset>
#include <vector>

class DecoderBase
{
public:
    DecoderBase() {}
    virtual ~DecoderBase() {}
    virtual std::vector<bool> GetDecodedFields() = 0;
};

class DecoderA : public DecoderBase
{
public:
    DecoderA() {}
    ~DecoderA() {}
    std::vector<bool> GetDecodedFields()
    {
        // assume we've decoded fileds number 1 and 10 here
        std::vector<bool> bits(100, false);
        bits[1] = true;
        bits[10] = true;
        return bits;
    }
};

class DecoderB : public DecoderBase
{
public:
    DecoderB() {}
    ~DecoderB() {}
    std::vector<bool> GetDecodedFields()
    {
        // assume we've decoded fileds number 11, 29, 110 & 142 here
        std::vector<bool> bits(200, false);
        bits[11] = 1;
        bits[29] = 1;
        bits[110] = 1;
        bits[142] = 1;
        return bits;
    }
};

class Container
{
public:
    Container() {}
    virtual ~Container() {}
    void SetDecoder(DecoderBase* decoder)
    {
        mDecoder = decoder;
    }
    DecoderBase* GetDecoder()
    {
        return mDecoder;
    }
private:
    DecoderBase* mDecoder;
};

int main()
{
    Container container;
    container.SetDecoder(new DecoderA());
    container.GetDecoder()->GetDecodedFields();
    std::cout << container.GetDecoder()->GetDecodedFields().size() << std::endl;
    return 0;
}

答案 1 :(得分:0)

这里的问题不是多态性。

您正在使用异类容器。

C ++中没有构造可以在不使用强制转换的情况下访问此类容器的元素。

干净的方式是dynamic_cast&lt;&gt;在容器元素上将元素转换为各自的类型。