在我的程序中,我有2个标题(IP和MAC标题),这些标题是' sons' GeneralHeader。所有常规,IP和MAC头类都具有PrintMe()函数。另外,我有一个包含GeneralHeaders列表的Packet类(该列表实际上可能有IP或MAC头:(没有IP defenition,缩短):
//Packet.h
class GeneralHeader {
public:
bool Valid;
HeaderType_t HeaderType; // MAC or IP
virtual void PrintMe();
};
class HW_MACHeader: public GeneralHeader {
public:
long unsigned DestAddr:48;
long unsigned SourceAddr:48;
virtual void PrintMe();
};
struct NetworkPacket_t {
NetworkPacket_t();
list<GeneralHeader> Headers;//TODO GeneralHeader
void PrintMe();
};
我很难实现PrintMe()方法,该方法将使用适当的MAC或IP PrintMe()方法(而不是GeneralHeader的基础PrintMe())打印GeneralHeaders列表:
//Packet.cpp
//This implementation prints GeneralHeaders :(
//(although MAC headers were added to the Headers list)
void NetworkPacket_t::PrintMe() {
list<GeneralHeader>::iterator it_H;
for (it_H = Headers.begin(); it_H != Headers.end(); ++it_H) {
it_H->PrintMe();
};
};
另一个尝试是将迭代器it_H强制转换为适当的MAC或IP头(根据HeaderType),但无论我试图如何投射它,它都不起作用,例如:
//Packet.cpp
//Casting implementation
//Here I get run error:
//terminate called after throwing an instance of 'std::bad_cast'
void NetworkPacket_t::PrintMe() {
list<GeneralHeader>::iterator it_H;
for (it_H = Headers.begin(); it_H != Headers.end(); ++it_H) {
switch (it_H->HeaderType) {
case General_Header_type:
std::cout << " General Header " << endl;
it_H->PrintMe();
break;
case MAC_Header_type:
dynamic_cast<HW_MACHeader&>(*it_H).PrintMe();
break;
default:
std::cout << " default" << endl;
};
};
};
我非常感谢你能提供任何帮助
答案 0 :(得分:1)
原因是您将object
而不是pointer
存储到了list
。它类似于:
HW_MACHeader hw;
GeneralHeader gh = hw;
您将child object
分配给parent object
,因此示例中的gh
实际上是hw
的第一部分。你可以阅读object slicing。
使用pointer
是正确的方法:
HW_MACHeader hw;
GeneralHeader *gh = &hw;
然后当你打电话
gh->PrintMe();
它将调用PrintMe
中的HW_MACHeader
函数。
看看这个:
#include <iostream>
#include <list>
using namespace std;
class GeneralHeader {
public:
bool Valid;
virtual void PrintMe() {cout << "General" << endl;}
};
class HW_MACHeader: public GeneralHeader {
public:
long unsigned DestAddr;
long unsigned SourceAddr;
virtual void PrintMe() {cout << "HW" << endl;}
};
struct NetworkPacket_t {
NetworkPacket_t(){}
list<GeneralHeader *> Headers;//TODO GeneralHeader
virtual void PrintMe();
};
void NetworkPacket_t::PrintMe() {
list<GeneralHeader *>::iterator it_H;
for (it_H = Headers.begin(); it_H != Headers.end(); ++it_H) {
(*it_H)->PrintMe();
}
}
int main()
{
NetworkPacket_t t;
HW_MACHeader t1;
GeneralHeader t2;
t.Headers.push_back(&t1);
t.Headers.push_back(&t2);
t.PrintMe();
return 0;
}
所有作业都将替换为pointer
而不是object
。输出是:
HW
General
答案 1 :(得分:0)
您可以将智能指针存储在容器中,
list<shared_ptr<GeneralHeader>>
然后虚函数将通过指向基类的指针按预期工作。