将基类转换为通过C ++中的std迭代器派生的

时间:2014-03-11 13:49:50

标签: c++ casting iterator

在我的程序中我有基于GeneralHeader的MacHeader,它派生自GeneralHeader和NetworkPacket,其成员标题是标准的GeneralHeader列表:

//Packet.h

enum HeaderType_t {General_Header_type, MAC_Header_type};

class GeneralHeader {
public:
    bool Valid;
    HeaderType_t HeaderType;
    void PrintMe();
};

struct MACHeader: public GeneralHeader {
    long unsigned DestAddr:48;
    long unsigned SourceAddr:48;
    void PrintMe();
};

struct Packet_t {
    list<GeneralHeader> Headers;//TODO GeneralHeader
    list<GeneralHeader>::iterator it_Header; //TODO GeneralHeader
    void PrintMe();
};

实现Packet_t的PrintMe(),它应该根据HeaderType打印所有Headers:如果有GeneralHeader - 它将使用GeneralHeader.PrintMe(),如果它是列表中的MACHeader,它将打印MACHeader。 PrintMe()) 我正努力将基于GeneralHeader的it_Header迭代器转换为Packet_t方法PrintMe()中的派生MACHeader:

//Packet.cpp

void GeneralHeader::PrintMe() {
    std::cout << "Valid " << GeneralHeader::Valid << endl;
    std::cout << "Header Type " << GeneralHeader::HeaderType << endl;
};

void HW_MACHeader::PrintMe() {

    std::cout << "------------------------   " << endl;
    std::cout << "----   MAC HEADER    ---   " << endl;
    std::cout << "------------------------   " << endl;

    GeneralHeader::PrintMe();

};

void NetworkPacket_t::PrintMe() {
    std::cout << "Valid Packet " << NetworkPacket_t::ValidPacket << endl;

    for (it_Header = Headers.begin(); it_Header != Headers.end(); it_Header++) {
        switch (it_Header->HeaderType) {
        case MAC_Header_type:           
            static_cast<HW_MACHeader*>(it_Header)->PrintMe();
            break;
        default:
            std::cout << "default" << endl;
        };
        it_Header++;
    };
};

错误:类型&#39; std :: _ List_iterator&#39;中的static_cast无效输入&#39; MACHeader *&#39;

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

期望/正常的多态方式是: 将PrintMe()重新定义为虚函数,以便不需要强制转换:

class GeneralHeader {
public:
    bool Valid;
    HeaderType_t HeaderType;
    virtual void PrintMe();
};

class MACHeader: public GeneralHeader {
    long unsigned DestAddr:48;
    long unsigned SourceAddr:48;
  public:    
     void PrintMe();
};

还使用指向GeneralHeader的指针向量:

list<GeneralHeader*>::iterator it_Header;

然后你可以:

(*it_Header)->printMe();

for循环会更简单:

  for (it_Header = Headers.begin(); it_Header != Headers.end();++it_Header)
       (*it_Header)->PrintMe();

我不知道为什么你需要it_Header成为该类的成员?它不能只是循环的本地吗?

答案 1 :(得分:1)

您需要取消引用it_Header来访问“底层”对象以解决编译器错误:

static_cast<HW_MACHeader*>(*it_Header)->PrintMe();

但是,这不会解决您的问题:您有一个GeneralHeader列表;因此,您希望向下转换为HW_MACHeader的实例,您需要使用dynamic_cast;这必须在引用或指针上完成:

dynamic_cast<HW_MACHeader&>(*it_Header).PrintMe();

上面的行采用it_Header引用的对象,并告诉编译器将其动态转换为HW_MACHeader类型的引用。

请注意,如果dynamic_cast无法转换为您想要的类型,{{1}}将返回空指针。

但是,这不是一种正确的方法。您应该遵循user2672165的建议,并使用虚函数。