for 循环与赋值运算符
For-loop vs assignment operator
直接赋值(即=
)是否与将某些内容转换为char*
然后使用for
循环逐个字节复制它相同?*
我想知道一种方法是否比另一种方法有优势。
struct A
{
int a;
int b;
} Test;
void* Buffer = malloc(1024);
// Casting and byte copying
for (int i=0; i != 8; i++)
{
((char*)Buffer)[i] = ((char*)Test)[i];
}
// Assignment
((A*)Buffer)[0] = Test;
* 所有类型都是可按位复制的。
编辑:根据答案,内存复制是否与"="相同
基本上是memcpy
所做的,并且对POD类型有效(假设sizeof(Test)
确实是8)。 但是,memcpy
几乎肯定会更快,因为编译器将具有特殊优化的汇编程序例程。
如果您尝试使用非 POD 类型执行此操作(或memcpy
),您将调用未定义的行为。 所以一般来说,你应该使用std::copy
或只使用分配。
您还应该避免在C++中使用malloc
,因为它不是类型安全的;如有必要,请使用new
或放置new
。
首先,这不是C++。这是丑陋的C。您正在手动分配大小为 1024 字节的内存块,并在裸指针中捕获其地址。此外,在代码示例中,您永远不会释放任何内存,从而泄漏 MB 内存。当涉及到C++时,这被认为是一种极其糟糕的做法。
C++不是带有类的 C,它是一种美丽的语言,只能通过将其与标准库结合使用并坚持更好的设计模式来表达自己,这些模式自然是 OO 编程带来的,尤其是 RAII,通用封装的概念,可以带来更好的内存管理。甚至new
在不必要的情况下都会被回避,更不用说malloc
了.
for (int i=0; i != 8; i++)
此外,您在这里做出了危险的假设,这可能会导致未定义的行为。
((char*)Buffer)[i] = ((char*)Test)[i];
我什至不打算对此发表评论。神圣。。。它不仅不好,而且不起作用。您正在尝试将位于堆栈上的struct
A
实例(常规"对象"/var)强制放入char*
中。你错过了&Test
.
如果您正在走这条路,请使用 memcpy,但请考虑改进您的C++方法。 Memcpy 有三个参数,一个目的地、一个源和以字节为单位的大小。确保两者匹配,您将获得一个快速的每字节副本。
使用 =
运算符的直接赋值绝对不一样作为复制字节的for
循环。 =
运算符尊重类型,它的作用将取决于类型。 逐字节复制是在大多数情况下未定义的行为。 在你的特殊情况下,我会期望编译器生成等效于处理数据作为一个无符号的长长,并复制它,只需要一两个机器说明。 但那只是因为您定义的类型。 通常,为编译器提供尽可能多的信息尽你所能,并信任它;它通常会做得更好。
这不是对OP问题的直接回答,而是对我认为他试图实现的目标的回答。
将格式化数据写入可传输格式是序列化,C++,有几种方法可以做到这一点。 有几件事需要考虑:格式应该是ASCII,XML,二进制,如果是二进制,应该是跨平台的(endianess,alignation)。 无论如何,将结构复制到字节缓冲区的幼稚方式几乎是不可取的。
您可以考虑以下选项:
- 当它可能采用ASCII格式时,最直接的方法是使用iostreams。
- boost.serialization
- 外部库(公平:Boost也是其中之一):Poco,谷歌缓冲区协议,...
- 滚动你自己的(基于转换基元)
另请参阅此问题
- 重载Singly Linked List中的赋值运算符
- 使用赋值运算符重载从类中返回jobject
- 标准库类型的赋值运算符的引用限定符
- 复制构造函数、赋值运算符C++
- 标准::变体的赋值运算符
- 移动赋值运算符;尝试引用已删除的函数.我该如何解决这个问题?
- 基类和派生类的多态赋值运算符
- 为用户定义的类正确调用复制构造函数/赋值运算符
- CRTP 中的复制赋值运算符 - gcc vs clang 和 msvc
- 为什么初始化时没有调用重载赋值运算符?
- 赋值运算符重载和自赋值
- C++矢量复制构造函数和赋值运算符是否也复制保留空间?
- Qt PL/SQL - 赋值运算符 - 字符串缓冲区太小
- 对 r 值使用移动赋值运算符时的异常
- 由于没有使用赋值运算符,映射的值是如何初始化的?
- 默认赋值运算符如何在实际 STL 中实现
- 使用赋值运算符复制 std::vector
- C++ 通过自定义赋值运算符隐式转换函数参数
- 双向循环列表中的赋值运算符以错误的顺序添加元素
- for 循环与赋值运算符