将结构转换为类 [英] casting a struct to a class

查看:86
本文介绍了将结构转换为类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以安全地将结构转换为类?

的内容大小相同,但是这个类的问题是具有

虚拟函数,这使得类的大小略大。

Is it possible to safely cast a struct to a class? The contents of both
are the same size, however there is the issue of the class having
virtual functions which make the size of the class slightly larger.

推荐答案



Leif Gruenwoldt写道:

Leif Gruenwoldt wrote:
是否可以安全地将结构转换为一类?
的内容大小相同,但是这个类具有虚函数的问题使得类的大小略大。
Is it possible to safely cast a struct to a class? The contents of both
are the same size, however there is the issue of the class having
virtual functions which make the size of the class slightly larger.




在不相关的类型之间进行转换是不安全的。如果没有

从一个转换为另一个,无论是由

语言设计隐含存在还是由您添加,那么就没有安全转换。

因此static_cast会给编译器错误(你使用的是C ++

强制转换而不是C风格吗?)你会知道转换是

不安全的时候你把它改成reinterpret_cast或写转换

例程。


如果你的结构和类是相关的类型,例如一个继承

来自另一个,然后你可以安全地将树投射到另一种类型

如果你知道你正在寻找一个指针或参考,那么你可以在树上下来

到那个子类/结构。


就主要机制而言,结构和类之间没有差别。

默认的封装级别是唯一的差异。一个类可以从结构继承

,反之亦然没问题。



It is not safe to cast between unrelated types. If there is no
conversion from one to the other, either implicitly existing by
language design or added by you, then there is no safe conversion.
Therefore a static_cast will give a compiler error (you ARE using C++
casts and not C style right?) and you will know that the conversion is
unsafe when you change it to reinterpret_cast or write the conversion
routines.

If your struct and class are related types, for instance one inherits
from the other, then you can cast up the tree to the other type safely
and down the tree if you KNOW you are looking at a pointer or reference
to that subclass/struct.

There is no diff between a struct and class as far as main mechanics.
Default level of encapsulation is the only diff. A class can inherit
from a struct and visa-versa no problem.


好的,谢谢诺亚。


我应该多给一些关于我为什么要这样做的背景

这个。


我的代码读取数据包具有某种定义格式的网络。

我有一个与数据包格式相匹配的结构。


struct

{

int i;

char c

} packet_t;


过去我会收回一个数据包并将其转换为packet_t类型。




char raw_packet [SIZE] = recv(...);

packet_t * p = reinterpret_cast< packet_t *> (raw_packet);


但是现在我想把我的结构转换成一个类,所以我有一个类似于他的东西:


类CPacket

{

public:


virtual~package(){};

虚拟字符串toString()const;


private:

int i;

char c;

};


我希望我可以继续我以前的方式,然后将我收到的原始

数据包投入课堂像这样的对象:


char * raw_packet = recv(...);

CPacket p = reinterpret_cast< CPacket *>(raw_packet);


然而,当我做这种类型的演员时,这些位不会排成一列。类

对象与结构大小不同


sizeof(CPacket)! = sizeof(packet_t)


类CPacket是4个字节,我相信更大。我想这是因为虚拟功能而导致的

vtable?无论如何,我想我已经没有了好运。祝你好运。我唯一的想法是做这样的事情。


class CPacket

{

...


私人:


packet_t m_packet; //匹配数据包的struct实例

}

Ok thanks Noah.

I should have given a bit more background about why I was wanting to do
this.

My code reads packets off the network that are of some defined format.
I have a struct that matches the format of the packet.

struct
{
int i;
char c
} packet_t;

In the past I would recv a packet and cast it to be of type packet_t.
i.e.

char raw_packet[SIZE] = recv(...);
packet_t * p = reinterpret_cast<packet_t *> ( raw_packet );

However now I would like to convert my struct to be a class so I have
something liket his:

class CPacket
{
public:

virtual ~packet() {};
virtual string toString() const;

private:
int i;
char c;
};

I was hoping I could continue on with my old ways and just cast the raw
packet I recieved into a class object like so:

char * raw_packet = recv(...);
CPacket p = reinterpret_cast<CPacket *>( raw_packet );

However when I do this type of cast the bits don''t line up. The class
object is not the same size as the struct

sizeof( CPacket ) ! = sizeof( packet_t )

The class CPacket is 4 bytes I believe larger. I guess this is for the
vtable because of the virtual functions? Anyways, I guess i''m out of
luck. My only thought is to do something like this.

class CPacket
{
...

private:

packet_t m_packet; // instance of struct that matches packet
}




Leif Gruenwoldt写道:

Leif Gruenwoldt wrote:
好的,谢谢诺亚。

我应该多给一些关于我为什么要这样做的背景。

我的代码读取网络上有一些定义格式的数据包。
我有一个与数据包格式相匹配的结构。

struct
{
int i;
char c
} packet_t;

过去我会收回一个数据包并将其转换为packet_t类型。


char raw_packet [SIZE] = recv(...);
packet_t * p = reinterpret_cast< packet_t *> (raw_packet);


无论如何,你所做的是icky ......你需要另一种方式,为什么不以正确的方式做?

但是现在我想将我的结构转换成一个类,所以我有一些东西可以用他的东西:

class CPacket
{
公开:

virtual~package(){};
虚拟字符串toString()const;

私有:
int i;
char c;
};


CPacket

{

public:

CPacket(const char * raw)

{memcpy(reinterpret_cast< char *>(& i),raw,sizeof(i)); memcpy(& c,

raw + sizeof(i),1); }

...

私人:

int i;

char c;

}


请注意,第一个memcpy不是完全可移植的,但可以预测。 raw需要与阅读机具有相同的字节对齐

以及所有......你需要知道前X个字节是一个int

填充并对齐就像你的我希望我可以继续我以前的方式,然后将我收到的原始数据包投入课堂
Ok thanks Noah.

I should have given a bit more background about why I was wanting to do
this.

My code reads packets off the network that are of some defined format.
I have a struct that matches the format of the packet.

struct
{
int i;
char c
} packet_t;

In the past I would recv a packet and cast it to be of type packet_t.
i.e.

char raw_packet[SIZE] = recv(...);
packet_t * p = reinterpret_cast<packet_t *> ( raw_packet );
What you are doing is icky anyway...you need another way so why not do
it the correct way?

However now I would like to convert my struct to be a class so I have
something liket his:

class CPacket
{
public:

virtual ~packet() {};
virtual string toString() const;

private:
int i;
char c;
};
CPacket
{
public:
CPacket(const char* raw)
{ memcpy(reinterpret_cast<char*>(&i), raw, sizeof(i)); memcpy(&c,
raw + sizeof(i), 1); }
...
private:
int i;
char c;
}

Note that the first memcpy is not exactly portable but is pretty
predictable. raw needs to have same byte alignment as reading machine
and all that...you need to know that the first X bytes are an int
padded and aligned just like your ints.
I was hoping I could continue on with my old ways and just cast the raw
packet I recieved into a class




你不要不想,真的你不会。


你的另一个想法也不会工作(虚拟功能)。你能做到最好吗

,我不推荐它:


CPacket {

public:

CPacket(char * raw){packet = reinterpret_cast< packet_t *>(raw); }


...没有析构函数删除内部指针!!不要它

...


私人:


struct packet_t {int i; char c; };

packet_t *包;

}

读完后
...


CPacket p(数据);或CPacket * p =新的CPacket(数据)


无论如何,这也不是便携式的。更好地做到这一点



You don''t want to, really you don''t.

Your other idea won''t work either (virtual functions). Best you could
do, and I don''t recommend it:

CPacket {
public:
CPacket(char * raw) { packet = reinterpret_cast<packet_t*>(raw); }

... no destructor deleting internal pointer!! Don''t want it
either...

private:

struct packet_t { int i; char c; };
packet_t * packet;
}

after a read...

CPacket p(data); or CPacket * p = new CPacket(data)

At any rate, that isn''t at all portable either. Better to do it right


这篇关于将结构转换为类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆