C++高阶 什么是Trivial types(普通类型)?

Aki 发布于 2022-11-27 287 次阅读


普通类型(Trivial Type)和标准布局类型(Standard-layout Type)以及POD类型 - 月光下的脚步 - 博客园 (cnblogs.com)

C++ POD笔记 - 知乎 (zhihu.com)

trivial意思是不重要的,trivial类型的直观表现是,它占据一片连续的内存,就像内建类型或者C的结构体类型、联合体类型一样,但它可以是class或者struct,它的成员可以有访问修饰符控制,这样的类型我们可以直接拷贝到char或者unsigned char数组,然后再拷贝回来,它仍然是原本的类型,换句话就是它可以序列化和反序列化为二进制,跟更加直白点就是可以通过std::memcpy_s安全拷贝。

满足以下三个条件,该类型就是trivial类型:

  • 1)有默认构造、析构、拷贝构造、拷贝赋值,移动构造,移动赋值函数,这些是由C++编译器提供默认的特殊成员函数。这不影响它有其他的构造、析构等函数,但它必须保留编译器默认创建的函数,这可以通过default关键字来实现。自己创建个空的函数也是不行的。
  • 2)没有虚函数(另一方面就是说不能继承于有虚函数的类),也没与虚基类
  • 3)数据成员也必须满足条件1和2
class Test
{
public:
	Test() = default;

	~Test() = default;

	Test(int a ):a(a){}

	Test& operator=(const Test& rhs) = default;

	int a;
};


int main()
{
	

	static_assert(is_trivial<Test>::value);  //true

	size_t len = sizeof(Test);   //4 Bytes

	char* p = new char[len];     //4 Bytes,char[4]

	Test a(11);   

	memcpy_s(p, len, &a,sizeof(Test));   //拷贝4个字节的数据到char[4]
  
	Test* s = reinterpret_cast<Test*>(p);  //指针转换
  
	cout << s->a << endl;   // 11


        for (size_t i = 0; i < 4; ++i)  //char[4]中每个元素存储二进制8位,一个字节
	{
		cout << int(p[i]) << endl; // 11 0 0 0 
	}

	delete[]p;

	

	return 0;
}