【发布时间】:2020-10-28 09:59:08
【问题描述】:
我有一个A类,如下:
struct MY_DATA
{
int m_nType;
union
{
DWORD m_dwBData;
double m_dCData;
} u;
};
class CClassA
{
public:
CClassA(BYTE* lpData, UINT uSize);
virtual ~CClassA(void);
MY_DATA m_Data;
};
CClassA::CClassA(BYTE* lpData, UINT uSize)
{
::memcpy(&m_Data, lpData, uSize);
}
CClassA::~CClassA(void)
{
}
还有一个从A类派生的B类,如下:
class CClassB : public CClassA
{
public:
CClassB(BYTE* lpData, UINT uSize);
virtual ~CClassB(void);
void ProcessBData()
{
m_Data.u.m_dwBData ++;
}
};
CClassB::CClassB(BYTE* lpData, UINT uSize)
: CClassA(lpData, uSize)
{
}
CClassB::~CClassB(void)
{
}
然后我收到一个大小为 uSize 的内存块 lpData。 uSize 与 MY_DATA 的大小相同。但是我事先并不知道m_nType。
我的目的是判断内存块的类型,并调用相应的处理函数,按照类型处理数据。
所以我在下面的代码 sn-p 中这样做:
CClassA a(lpData, uSize);
if (a.m_Data.m_nType == 0)
{
CClassB& b = (CClassB&)a;
b.ProcessBData();
}
我会使用一个内存块来创建一个Class A的实例,那么如果数据的类型是0,那么我们就知道数据是B类的,那么我将把原始实例提升到它的子类ClassB这样我们就可以调用 ProcessBData 来处理特定于 B 类的数据。
但是,我怀疑这是否可行,因为 B 类是 A 的子类,因此通过将基类提升到其子类,它将包含比 A 类更多的条目,这会导致问题吗?
另一种解决方案是在知道类型为 0 后创建一个新的 Class B 实例,具有相同的内存块。但是,这会降低性能,因为我们将内存块复制了两次,一次复制到 A 类,一次复制到 B 类。
那么如何解决这样的delimma呢?
谢谢
【问题讨论】:
-
如果基类实际上不是子类,则绝对不要将基类转换为子类。在我看来,实例化哪个类的决定应该由工厂函数根据手头的数据来处理。
-
为什么不简单地实现一些移动语义呢?或者,如果旧对象必须保持有序,则使另一个类不是子类,而是存储指向第一个类的指针。
-
我也确实认为指针是正确的方法。工厂如何创建一个包含指针的对象。
-
您的代码 sn-p 包含未定义的行为。在某些情况下,它可能似乎适用于某些编译器,但在其他情况下会失败。如果
ClassB有额外的数据成员,那肯定是非常危险的。 -
来自“写出完美的问题”codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question >
One trap that many posters fall into is to ask how to achieve some “small” aim, but never say what the larger aim is.那么你的目标是什么?什么是lpData和uSize,您如何使用它们?你如何初始化m_Data?为什么在这种情况下需要继承?没有这些信息就没有困境,因为不清楚选项是什么。
标签: c++ superclass base-class