首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

C++之std::is_pod(平凡的数据)

  • 24-03-12 16:27
  • 2853
  • 10145
blog.csdn.net

概述

        POD(Plain old data), 平凡的数据, 也是旧 C 语言中的那些类型。 POD 类型还包括标量类型。 POD 类类型是既平凡(可以静态初始化)trivial和标准布局Standard layout(这是一个简单的数据结构,如结构和联合)的类类型。

        std::is_pod的原型:template is_pod;

        模板只能有类型 T 的参数,并检查给定的类型是否为普通旧数据类型,它返回一个布尔值,如果给定类型是普通旧数据,则返回 true,如果给定类型不是普通旧数据,则返回 false。

C++基础回顾

1、 C++定义一个类 class CTest{}; 系统编译器会默认生成的函数有:

            1)默认构造函数,没有参数, 如: CTest() = default;

            2)拷贝构造函数,  如:CTest(const CTest& test) = default;

            3)拷贝赋值操作符, 如:CTest& operator=(const CTest& test) =default;

            4)  默认析构函数, 如:~CTest() =default;

            5)移动构造函数, 如: CTest(const CTest&& test) = default;

            6)移动赋值操作符,如:CTest& operator=(CTest&& test) =default;

2、当自定义类型时,如果编码实现了任意一个构造函数,则编译器将不会自动合成默认构造函数。C++11中可使用=default显示声明默认构造函数,加了关键字=default生成的构造函数和默认构造函数是一个效果

3、当自定义类型时,如果需要限制类的某些构造函数调用,在C++11中可使用=delete来阻止用户的调用

Trivial 类型

极简 (trivial),可以通过std::is_trivial::value判断,判断trivial的条件是:

  • 有平凡的构造函数
  • 有平凡的拷贝构造函数
  • 有平凡的移动构造函数
  • 有平凡的拷贝赋值运算符
  • 有平凡的移动赋值运算符
  • 有平凡的析构函数
  • 不能包含虚函数
  • 不能包含虚基类
  • 成员变量及基类也要满足上述条件

判断下面定义的几个struct是否是trivial类型:

  1. class MyTest1{
  2. int m1;
  3. };
  4. class MyTest2{
  5. public:
  6. MyTest2(double val):m1(val){}
  7. private:
  8. double m1;
  9. };
  10. class MyTest3{
  11. public:
  12. MyTest2(int val = 0):n(val){}
  13. private:
  14. int n;
  15. };
  16. class MyTest4{
  17. public:
  18. MyTest4(){}
  19. MyTest4(int val):n(val){}
  20. private:
  21. int n;
  22. };
  23. class MyTest5{
  24. public:
  25. MyTest5() = default;
  26. MyTest5(int val):n(val){}
  27. private:
  28. int n;
  29. };
  30. class MyTest6{
  31. public:
  32. MyTest6() = default;
  33. MyTest6(MyTest6&& val);
  34. private:
  35. MyTest6* m_pTest;
  36. };
  37. printf("is_trivial:%d\n", std::is_trivial::value);// true
  38. printf("is_trivial:%d\n", std::is_trivial::value);// false
  39. printf("is_trivial:%d\n", std::is_trivial::value);// false
  40. printf("is_trivial:%d\n", std::is_trivial::value);// false
  41. printf("is_trivial:%d\n", std::is_trivial::value);// true
  42. printf("is_trivial:%d\n", std::is_trivial::value);// false

标准布局 (standard layout)

标准布局 (standard layout),可以通过std::is_standard_layout::value判断,满足标准布局的条件有:

  • 所有非静态成员有相同的访问权限
  • 继承树中最多只能有一个类有非静态数据成员
  • 子类的第一个非静态成员不可以是基类类型
  • 没有虚函数
  • 没有虚基类
  • 所有非静态成员都符合标准布局类型
  1. struct S1{
  2. int i;
  3. };
  4. struct B1{
  5. void foo(){}
  6. };
  7. struct S2 : public B1{
  8. int i;
  9. };
  10. struct B2{
  11. int n;
  12. };
  13. struct S3 : public B2{};
  14. struct S4 : public B2{
  15. int i;
  16. };
  17. struct S5 : public B1{
  18. B1 b;
  19. int m;
  20. };
  21. struct S6 : public B1{
  22. int m;
  23. B1 b;
  24. };
  25. struct S7 : virtual public B1{};
  26. struct S8{
  27. S8(int val):mVal(val){}
  28. private :
  29. int mVal;
  30. };
  31. // Trivial but not standard-layout
  32. struct S9{
  33. public:
  34. int m;
  35. private:
  36. int n;
  37. };
  38. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
  39. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
  40. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
  41. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// false
  42. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// false
  43. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
  44. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// false
  45. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
  46. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// false
  47. printf("\n\n");
  48. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
  49. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true

总结

POD 类 是满足以下所有条件的类:

  • 它是聚合体,
  • 没有用户声明的复制赋值运算符,
  • 没有用户声明的析构函数,并且
  • 没有具有非 POD 类类型(或这种类型的数组)的非静态数据成员。
(C++11 前)
  • 它是平凡类,
  • 它是标准布局类,并且
  • 没有具有非 POD 类类型(或这种类型的数组)的非静态数据成员。
(C++11 起)


POD 结构体 是非联合体的 POD 类。POD 联合体 是满足 POD 类条件的联合体。

POD 属性的使用被弃用。用户代码应该期待或要求平凡或标准布局属性,或者它们两者。

(C++20 起)

概述

        POD(Plain old data), 平凡的数据, 也是旧 C 语言中的那些类型。 POD 类型还包括标量类型。 POD 类类型是既平凡(可以静态初始化)trivial和标准布局Standard layout(这是一个简单的数据结构,如结构和联合)的类类型。

        std::is_pod的原型:template is_pod;

        模板只能有类型 T 的参数,并检查给定的类型是否为普通旧数据类型,它返回一个布尔值,如果给定类型是普通旧数据,则返回 true,如果给定类型不是普通旧数据,则返回 false。

C++基础回顾

1、 C++定义一个类 class CTest{}; 系统编译器会默认生成的函数有:

            1)默认构造函数,没有参数, 如: CTest() = default;

            2)拷贝构造函数,  如:CTest(const CTest& test) = default;

            3)拷贝赋值操作符, 如:CTest& operator=(const CTest& test) =default;

            4)  默认析构函数, 如:~CTest() =default;

            5)移动构造函数, 如: CTest(const CTest&& test) = default;

            6)移动赋值操作符,如:CTest& operator=(CTest&& test) =default;

2、当自定义类型时,如果编码实现了任意一个构造函数,则编译器将不会自动合成默认构造函数。C++11中可使用=default显示声明默认构造函数,加了关键字=default生成的构造函数和默认构造函数是一个效果

3、当自定义类型时,如果需要限制类的某些构造函数调用,在C++11中可使用=delete来阻止用户的调用

Trivial 类型

极简 (trivial),可以通过std::is_trivial::value判断,判断trivial的条件是:

  • 有平凡的构造函数
  • 有平凡的拷贝构造函数
  • 有平凡的移动构造函数
  • 有平凡的拷贝赋值运算符
  • 有平凡的移动赋值运算符
  • 有平凡的析构函数
  • 不能包含虚函数
  • 不能包含虚基类
  • 成员变量及基类也要满足上述条件

判断下面定义的几个struct是否是trivial类型:

  1. class MyTest1{
  2. int m1;
  3. };
  4. class MyTest2{
  5. public:
  6. MyTest2(double val):m1(val){}
  7. private:
  8. double m1;
  9. };
  10. class MyTest3{
  11. public:
  12. MyTest2(int val = 0):n(val){}
  13. private:
  14. int n;
  15. };
  16. class MyTest4{
  17. public:
  18. MyTest4(){}
  19. MyTest4(int val):n(val){}
  20. private:
  21. int n;
  22. };
  23. class MyTest5{
  24. public:
  25. MyTest5() = default;
  26. MyTest5(int val):n(val){}
  27. private:
  28. int n;
  29. };
  30. class MyTest6{
  31. public:
  32. MyTest6() = default;
  33. MyTest6(MyTest6&& val);
  34. private:
  35. MyTest6* m_pTest;
  36. };
  37. printf("is_trivial:%d\n", std::is_trivial::value);// true
  38. printf("is_trivial:%d\n", std::is_trivial::value);// false
  39. printf("is_trivial:%d\n", std::is_trivial::value);// false
  40. printf("is_trivial:%d\n", std::is_trivial::value);// false
  41. printf("is_trivial:%d\n", std::is_trivial::value);// true
  42. printf("is_trivial:%d\n", std::is_trivial::value);// false

标准布局 (standard layout)

标准布局 (standard layout),可以通过std::is_standard_layout::value判断,满足标准布局的条件有:

  • 所有非静态成员有相同的访问权限
  • 继承树中最多只能有一个类有非静态数据成员
  • 子类的第一个非静态成员不可以是基类类型
  • 没有虚函数
  • 没有虚基类
  • 所有非静态成员都符合标准布局类型
  1. struct S1{
  2. int i;
  3. };
  4. struct B1{
  5. void foo(){}
  6. };
  7. struct S2 : public B1{
  8. int i;
  9. };
  10. struct B2{
  11. int n;
  12. };
  13. struct S3 : public B2{};
  14. struct S4 : public B2{
  15. int i;
  16. };
  17. struct S5 : public B1{
  18. B1 b;
  19. int m;
  20. };
  21. struct S6 : public B1{
  22. int m;
  23. B1 b;
  24. };
  25. struct S7 : virtual public B1{};
  26. struct S8{
  27. S8(int val):mVal(val){}
  28. private :
  29. int mVal;
  30. };
  31. // Trivial but not standard-layout
  32. struct S9{
  33. public:
  34. int m;
  35. private:
  36. int n;
  37. };
  38. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
  39. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
  40. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
  41. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// false
  42. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// false
  43. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
  44. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// false
  45. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
  46. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// false
  47. printf("\n\n");
  48. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
  49. printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true

总结

POD 类 是满足以下所有条件的类:

  • 它是聚合体,
  • 没有用户声明的复制赋值运算符,
  • 没有用户声明的析构函数,并且
  • 没有具有非 POD 类类型(或这种类型的数组)的非静态数据成员。
(C++11 前)
  • 它是平凡类,
  • 它是标准布局类,并且
  • 没有具有非 POD 类类型(或这种类型的数组)的非静态数据成员。
(C++11 起)


POD 结构体 是非联合体的 POD 类。POD 联合体 是满足 POD 类条件的联合体。

POD 属性的使用被弃用。用户代码应该期待或要求平凡或标准布局属性,或者它们两者。

(C++20 起)
注:本文转载自blog.csdn.net的流星雨爱编程的文章"https://blog.csdn.net/haokan123456789/article/details/135015318"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top