gpt4 book ai didi

c++ - 我可以安全地 memset 一个具有用户定义构造函数的非平凡 C++ 结构吗?

转载 作者:行者123 更新时间:2023-12-03 07:12:23 24 4
gpt4 key购买 nike

我知道 POD 类可以安全地进行 memset。在 c++17(?) 中,std::is_pod 被 std::is_standard_layout 和 std::is_trivial 取代。 如果一个非平凡但标准的布局结构仅包含 char[] 数据和用户定义的构造函数,它是否可以安全地 memset。

具有数十个 char[] 成员变量的遗留类。

#include <cstring>
#include <memory>
#include <iostream>
#include <type_traits>

struct A
{
// dozens of fields all char[] which need to initialized to '0'
char foo[10]; // example char[] field
// dozens of other fields all char[] which need to be initialized to non '0'

struct AA
{
char bar[10];
// dozens of other fields
} sub[7];
};

// What I want to turn struct A into
struct B
{
B()
{
// My question: Is this permissible?
std::memset(this, '0', sizeof(*this));

// Initialize all the other member variables that need different values
std::memset(foo, ' ', sizeof(foo));
}

// dozens of fields all char[] which need to initialized to '0'
char foo[10]; // example char[] field
// dozens of other fields all char[] which need to be initialized to other values in constructor

struct BB
{
char bar[10];
// dozens of other fields
} sub[7];
};

int main(int argc, char* argv[])
{
bool isTrivialA = std::is_trivial<A>::value;
bool isStandardLayoutA = std::is_standard_layout<A>::value;
bool isTrivialCopyA = std::is_trivially_copyable<A>::value;

std::cout << "Is A trivial: " << isTrivialA << std::endl;
std::cout << "Is A standard layout: " << isStandardLayoutA << std::endl;;
std::cout << "Is A trivial copy: " << isTrivialCopyA << std::endl << std::endl;

bool isTrivialB = std::is_trivial<B>::value;
bool isStandardLayoutB = std::is_standard_layout<B>::value;
bool isTrivialCopyB = std::is_trivially_copyable<B>::value;

std::cout << "Is B trivial: " << isTrivialB << std::endl;
std::cout << "Is B standard layout: " << isStandardLayoutB << std::endl;
std::cout << "Is B trivial copy: " << isTrivialCopyB << std::endl;
}

现有代码只是在使用对象时对其进行内存设置。

A legacy;
memset(&legacy, '0', sizeof(legacy));

我想在更新的结构 B 上调用用户定义的构造函数,因为除了“0”之外,还有许多字段实际上需要初始化为不同的值。我知道我可以使用非成员函数来初始化值,但这看起来很笨拙。

B newer; // Call user defined constructor

在 B 中使用“this”指针的 memset() 定义的构造函数是否安全/允许?

最佳答案

没有允许“memset”对对象进行有效操作的机制。而这个包括“POD”;标准中从来没有任何内容表示可以将数据直接任意写入 POD 类型的对象表示。

平凡可复制使得可以将对象表示复制到存储中,并且可以将从该类型的有效实例中获取的此类数据直接复制到该类型的另一个实例中。但即使是这样的指定也从未允许将值直接任意设置到对象的表示中。

不过,实际上,只使用 (){} 对对象进行值初始化会更容易,这(如果它没有构造函数,因此适合旧的 POD 定义)将值初始化成员。

关于c++ - 我可以安全地 memset 一个具有用户定义构造函数的非平凡 C++ 结构吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61064704/

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