使用memmove在c++构造函数中初始化整个对象
Using memmove to initialize entire object in constructor in C++
使用memmove/memcpy初始化带有构造函数参数的对象是否安全?
似乎没有人使用这种方法,但当我尝试它时效果很好。
在堆栈中传递参数是否会导致问题?
假设我有一个类foo
如下,
class foo
{
int x,y;
float z;
foo();
foo(int,int,float);
};
我可以像下面这样使用memmove初始化变量吗?
foo::foo(int x,int y,float z)
{
memmove(this,&x, sizeof(foo));
}
这是未定义的行为。
显示的代码没有尝试初始化类变量。它尝试将memmove
()放到类指针上,并假设类的大小为2*sizeof(int)+sizeof(float)
。c++标准不能保证。
此外,所示代码还假设传递给构造函数的参数的布局与此POD
成员的布局相同。这也是c++标准中没有规定的。
使用memmove
初始化单个类成员是安全的。例如,以下是安全的:
foo::foo(int x_,int y_,float z_)
{
memmove(&x, &x_, sizeof(x));
memmove(&y, &y_, sizeof(y));
memmove(&z, &z_, sizeof(z));
}
当然,这没有什么用处,但这是安全的。
不,这是不安全的,因为根据标准,由于对齐/填充的原因,成员不能保证立即在彼此之后。更新后,情况会更糟,因为传入参数的位置和顺序使用起来不安全。
我们应该忘记小的效率,说大约97%的时间:过早的优化是万恶之源。然而,我们不应该错过这关键的3%的机会。——高德纳
你不应该尝试优化你不确定需要的代码。我建议您在能够执行这种优化之前,先对代码进行配置。这样,您就不会浪费时间改进一些代码的性能,而这些代码不会影响应用程序的整体性能。
通常,编译器足够聪明,可以猜测你想用代码做什么,并生成高效的代码,保持相同的功能。为此,您应该确保启用了编译器优化(-Olevel
标志或通过编译器命令参数切换单个优化)。
例如,当编译器确定这样做是直接的(例如,数据是连续的)时,我看到一些编译器将std::copy
转换为memcpy。
不,不安全。这是未定义的行为。
和代码
foo::foo(int x,int y,float z)
{
memmove(this,&x, sizeof(foo));
}
与使用初始化列表
相比,甚至没有节省任何输入。
foo::foo(int x,int y,float z) : x(x), y(y), z(z)
{ }
相关文章:
- C++使用整数的压缩数组初始化对象
- 如何使用cudaMallocManaged在指针位置初始化对象?(C++)
- 在 c++ 中初始化对象
- C++ 手动分配和初始化对象
- 使用运算符"="在C++中用值初始化对象
- 当我不需要数据库中的所有值时,如何部分初始化 c++ 对象?
- 如何初始化对象数组?
- 在C++中使用默认构造函数初始化对象的不同方法
- 使用默认构造函数初始化对象的不同方法
- 是否可以在编译时初始化对象的 C 样式函数指针,以便它调用对象的成员函数?
- 如何在线程中初始化对象,然后在其他地方使用它?
- 在没有默认构造函数时使用垃圾数据初始化对象
- 如果在 C++ 构造函数中以错误的顺序初始化对象数据,会发生什么类型的错误
- 初始化对象以在 C++08 中作为参数传递的首选语法是什么?
- 在 c++ 中复制对未初始化对象的引用
- 在成员变量在另一个文件中发生更改后,调用与初始化对象分开的函数
- 在不放置新运算符的情况下,在预分配的内存上使用虚函数初始化对象 - 这可能吗?如果没有,为什么
- 复制 CTOR 与赋值运算符以初始化对象(性能)
- 当您通过分配初始化C 对象时会发生什么
- 获取未初始化对象成员的地址是否定义良好?