当前位置:  开发笔记 > 编程语言 > 正文

编码恐怖或精彩创意的C++示例?

如何解决《编码恐怖或精彩创意的C++示例?》经验,为你挑选了6个好方法。

在以前的雇主,我们写的二进制消息必须"通过电线"到其他计算机.每条消息都有一个标准标题,例如:

class Header
{
    int type;
    int payloadLength;
};

所有数据都是连续的(标题,紧接着是数据).我们希望得到有效载荷,因为我们有一个指向标题的指针.传统上,您可能会说:

char* Header::GetPayload()
{
    return ((char*) &payloadLength) + sizeof(payloadLength);
}

甚至:

char* Header::GetPayload()
{
    return ((char*) this) + sizeof(Header);
}

这看起来很冗长,所以我想出了:

char* Header::GetPayload()
{
    return (char*) &this[1];
}

起初看起来相当令人不安,可能使用起来太奇怪 - 但非常紧凑.关于它是辉煌还是令人憎恶,有很多争论.

那么它是什么 - 犯罪编码,还是不错的解决方案?你曾经有过类似的权衡吗?

- 更新:

我们确实尝试过零大小的数组,但当时编译器发出了警告.我们最终采用了以下技术:消息来自Header.它在实践中很有效,但原则上你说的是一条消息IsA Header - 这看起来有点尴尬.



1> James Curran..:

我会去打击编码犯罪.

两种方法都将生成完全相同的目标代码.第一个是明确的意图.第二个是非常混乱,唯一的优点是它可以节省几次击键.(只是学习freakin'类型).

另外,请注意NEITHER方法可以保证正常工作.sizeof()一个对象包括用于字对齐的填充,因此如果标题是:

class Header
{
    int type;
    int payloadLength;
    char  status;
};

您描述的两种方法都将使有效负载从Header + 12开始,而最有可能它实际上从Header + 9开始.


哦等等!你可以用以下方法使它更难以理解:return(char*)&1 [this]
绝不应该通过线路使用编译器结构.Endianness问题,项目之间的编译器填充问题,CPU字大小等.了解如何使用真正的解决方案.谷歌StreamBuffers(例如)更清晰,语言独立.

2> Menkboy..:

就个人而言,我认为如果有犯罪,那就是要求有效载荷的标题.

但只要你这样做,'这+ 1'就像任何一样好.

理由:'&this [1]'是一个通用的代码片段,不需要你深入挖掘类定义来完全理解,并且当有人更改类的名称或内容时不需要修复.

顺便说一句,第一个例子是真正的反人类罪.将一个成员添加到类的末尾,它将失败.移动类中的成员,它将失败.如果编译器填充类,它将失败.

此外,如果您假设编译器的类/结构布局与您的数据包布局匹配,那么您应该了解所讨论的编译器是如何工作的.例如.在MSVC你可能想知道#pragma pack.

PS:有多少人认为"这+ 1"或"&[1]"很难阅读或理解,这有点可怕.



3> tvanfosson..:

您依赖编译器以特定方式布置类.我会将消息定义为结构(我定义布局),并有一个封装消息并为其提供接口的类.清除代码=良好的代码."可爱"代码=糟糕(难以维护)的代码.

struct Header
{
    int type;
    int payloadlength;
}
struct MessageBuffer
{
   struct Header header;
   char[MAXSIZE] payload;
}

class Message
{
  private:
   MessageBuffer m;

  public:
   Message( MessageBuffer buf ) { m = buf; }

   struct Header GetHeader( )
   {
      return m.header;
   }

   char* GetPayLoad( )
   {
      return &m.payload;
   }
}

自从我编写任何C++以来已经有一段时间了,所以请原谅语法方面的任何问题.只是想传达一般的想法.



4> Roddy..:

这是一个常见的问题,但你真正想要的是这个.

class Header
{
    int type;
    int payloadLength;
    char payload[0];

};

char* Header::GetPayload()
{
    return payload;
}



5> Tom Ritter..:

我的投票是Coding Horror.不要误会我的意思,这很聪明 - 但是你要为自己节省一整个额外的操作,代价是使代码更难以理解和阅读.我不认为这种权衡是值得的.



6> ypnos..:

如果标题需要"返回"未包含在其中的数据,我认为从一开始就存在缺陷.

正如你已经把自己置于这些hackish理由,我真的很喜欢你想出的.

但请注意,这不是一场选美比赛.您应该找到完全不同的解决方案.对于你提出的三个版本的GetPayload(),如果没有你的进一步解释,我不明白到底是怎么回事.

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有