gpt4 book ai didi

c++ - 我可以将基类提升为子类吗?

转载 作者:行者123 更新时间:2023-12-01 14:18:15 26 4
gpt4 key购买 nike

我有一个 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。

我的目的是判断内存块的类型,并按照类型调用相应的处理函数来处理数据。

所以我在下面的代码片段中这样做:

    CClassA a(lpData, uSize);

if (a.m_Data.m_nType == 0)
{
CClassB& b = (CClassB&)a;
b.ProcessBData();
}

我将使用一个内存块创建一个类A的实例,然后如果数据的类型是0,那么我们就知道数据是类B的,然后我将原始实例提升到它的子类ClassB这样我们就可以调用 ProcessBData 来处理特定于类 B 的数据。

但是,我怀疑这是否可行,因为 B 类是 A 的子类,所以它将包含比 A 类更多的条目,通过将基类提升到其子类,这会导致问题吗?

另一种解决方案是在知道类型为 0 后,使用相同的内存块创建 B 类的新实例。但是,这会降低性能,因为我们将内存块复制了两次,一次复制到 A 类,一次复制到 B 类。

那么如何解决这样的困境呢?

谢谢

最佳答案

如果不添加/获取有关数据内容的任何类型信息,则无法在运行时获取类型信息。如果您能以某种方式获取类型信息,则有一些解决方案

  1. 要么你在处理它之前设置struct MY_DATA::m_nType,通过查看数据获取它的类型(也许你的数据中有某种标识符,特定类型的特定值范围,不同数据类型的大小不同)。
  2. 文档为您提供了一些关于您将收到何种信息的信息
  3. 您可以更改MY_DATA 的声明并使用Runtime Type information

解决方案 1:例如,如果是 DWORD 和 double,您可以使用数据的大小

std::cout << sizeof(unsigned int) << std::endl;
>> 4
std::cout << sizeof(bouble) << std::endl;
>> 8

如果您有权访问数据的原始创建。

解决方案 2:好吧,显然是查看您的文档或询问提供数据的开发人员。

解决方案 3:使用 Runtime Type information为您的 MY_DATA 结构。这可能如下所示:

我的类.h

#pragma once

#include <cstdint>

struct MY_DATA{
virtual ~MY_DATA() {};
};

struct MY_DATA_B : public MY_DATA{
unsigned int data;
};

struct MY_DATA_C : public MY_DATA{
double data;
};

class CClassB {
public:
CClassB(MY_DATA* lpData);
virtual ~CClassB(void);

void myMethodB();

private:
MY_DATA_B* m_Data;
};

class CClassC {
public:
CClassC(MY_DATA* lpData);
virtual ~CClassC(void);

void myMethodC();

private:
MY_DATA_C* m_Data;
};

我的类.cpp

#include "myclass.h"

#include <cstring>
#include <iostream>

CClassB::CClassB(MY_DATA* lpData){
m_Data = new MY_DATA_B;
memcpy(m_Data, lpData, sizeof(MY_DATA_B));
}

CClassB::~CClassB(){
delete m_Data;
}

void CClassB::myMethodB(){
std::cout << "MY_DATA_B data: " << m_Data->data << std::endl;
}

CClassC::CClassC(MY_DATA* lpData){
m_Data = new MY_DATA_C;
memcpy(m_Data, lpData, sizeof(MY_DATA_C));
}

CClassC::~CClassC(){
delete m_Data;
}

void CClassC::myMethodC(){
std::cout << "MY_DATA_C data: " << m_Data->data << std::endl;
}

主要.cpp

#include "myclass.h"

#include <iostream>
#include <typeinfo>


void execute(MY_DATA * ptr){
if(typeid(*ptr) == typeid(MY_DATA_B)){
CClassB a(ptr);
a.myMethodB();
}else if(typeid(*ptr) == typeid(MY_DATA_C)){
CClassC a(ptr);
a.myMethodC();
}
}

int main(){
MY_DATA_B b;
b.data = 5;
MY_DATA_C c;
c.data = 3.1;

MY_DATA * ptr = &b;
MY_DATA * ptr2 = &c;

execute(ptr);
execute(ptr2);

return 0;
}

这将导致以下输出:

MY_DATA_B data: 5
MY_DATA_C data: 3.1

如果你真的只是得到一堆内存而没有任何关于它的内容的进一步信息并且想要获得信息的类型=>那么你的设计就无法修复了。

关于c++ - 我可以将基类提升为子类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62787204/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com