在c++中通过std迭代器将基类强制转换为派生类



在我的程序中,我有基本的GeneralHeader, MacHeader派生自GeneralHeader和NetworkPacket,成员header是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打印所有头:如果有一个GeneralHeader -它将使用GeneralHeader.PrintMe(),如果它是MACHeader在列表中-它将打印MACHeader.PrintMe())我正在努力将it_Header迭代器从基本GeneralHeader转换为Packet_t方法中的派生MACHeader PrintMe():

//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++;
    };
};

错误:从类型'std::_List_iterator'到类型'MACHeader*'的static_cast无效

谢谢你的帮助。

期望的/正常的多态方式是:将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的vector指针:

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是类的成员?就不能只在本地循环吗?

你需要解引用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不能转换为你想要的类型,它将返回一个空指针。

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

最新更新