zoukankan      html  css  js  c++  java
  • C++11:POD数据类型

    目录(?)[+]

    啥是POD类型?

    POD全称Plain Old Data。通俗的讲,一个类或结构体通过二进制拷贝后还能保持其数据不变,那么它就是一个POD类型。


    平凡的定义

    1.有平凡的构造函数

    2.有平凡的拷贝构造函数

    3.有平凡的移动构造函数

    4.有平凡的拷贝赋值运算符

    5.有平凡的移动赋值运算符

    6.有平凡的析构函数

    7.不能包含虚函数

    8.不能包含虚基类


    1. #include "stdafx.h"  
    2. #include <iostream>  
    3.   
    4. using namespace std;  
    5.   
    6. class A { A(){} };  
    7. class B { B(B&){} };  
    8. class C { C(C&&){} };  
    9. class D { D operator=(D&){} };  
    10. class E { E operator=(E&&){} };  
    11. class F { ~F(){} };  
    12. class G { virtual void foo() = 0; };  
    13. class H : G {};  
    14. class I {};  
    15.   
    16. int _tmain(int argc, _TCHAR* argv[])  
    17. {  
    18.     std::cout << std::is_trivial<A>::value << std::endl;  // 有不平凡的构造函数  
    19.     std::cout << std::is_trivial<B>::value << std::endl;  // 有不平凡的拷贝构造函数  
    20.     std::cout << std::is_trivial<C>::value << std::endl;  // 有不平凡的拷贝赋值运算符  
    21.     std::cout << std::is_trivial<D>::value << std::endl;  // 有不平凡的拷贝赋值运算符  
    22.     std::cout << std::is_trivial<E>::value << std::endl;  // 有不平凡的移动赋值运算符  
    23.     std::cout << std::is_trivial<F>::value << std::endl;  // 有不平凡的析构函数  
    24.     std::cout << std::is_trivial<G>::value << std::endl;  // 有虚函数  
    25.     std::cout << std::is_trivial<H>::value << std::endl;  // 有虚基类  
    26.   
    27.     std::cout << std::is_trivial<I>::value << std::endl;  // 平凡的类  
    28.   
    29.     system("pause");  
    30.     return 0;  
    31. }  


    运行结果



    标准布局的定义

    1.所有非静态成员有相同的访问权限

    2.继承树中最多只能有一个类有非静态数据成员

    3.子类的第一个非静态成员不可以是基类类型

    4.没有虚函数

    5.没有虚基类

    6.所有非静态成员都符合标准布局类型


    1. #include "stdafx.h"  
    2. #include <iostream>  
    3.   
    4. using namespace std;  
    5.   
    6. class A   
    7. {   
    8. private:  
    9.     int a;  
    10. public:  
    11.     int b;  
    12. };  
    13.   
    14. class B1  
    15. {  
    16.     static int x1;  
    17. };  
    18.   
    19. class B2  
    20. {  
    21.     int x2;  
    22. };  
    23.   
    24. class B : B1, B2  
    25. {  
    26.     int x;  
    27. };  
    28.   
    29. class C1 {};  
    30. class C : C1  
    31. {  
    32.     C1 c;  
    33. };  
    34.   
    35. class D { virtual void foo() = 0; };  
    36. class E : D {};  
    37. class F { A x; };  
    38.   
    39. int _tmain(int argc, _TCHAR* argv[])  
    40. {  
    41.     std::cout << std::is_standard_layout<A>::value << std::endl;  // 违反定义1。成员a和b具有不同的访问权限  
    42.     std::cout << std::is_standard_layout<B>::value << std::endl;  // 违反定义2。继承树有两个(含)以上的类有非静态成员  
    43.     std::cout << std::is_standard_layout<C>::value << std::endl;  // 违反定义3。第一个非静态成员是基类类型  
    44.     std::cout << std::is_standard_layout<D>::value << std::endl;  // 违反定义4。有虚函数  
    45.     std::cout << std::is_standard_layout<E>::value << std::endl;  // 违反定义5。有虚基类  
    46.     std::cout << std::is_standard_layout<F>::value << std::endl;  // 违反定义6。非静态成员x不符合标准布局类型  
    47.   
    48.     system("pause");  
    49.     return 0;  
    50. }  


    运行结果




    POD的使用

    当一个数据类型满足了”平凡的定义“和”标准布局“,我们则认为它是一个POD数据。可以通过std::is_pod来判断一个类型是否为POD类型。

    如文章开头说的,一个POD类型是可以进行二进制拷贝的,看看下面的例子。


    1. #include "stdafx.h"  
    2. #include <iostream>  
    3. #include <Windows.h>  
    4.   
    5. using namespace std;  
    6.   
    7. class A   
    8. {   
    9. public:  
    10.     int x;  
    11.     double y;  
    12. };  
    13.   
    14. int _tmain(int argc, _TCHAR* argv[])  
    15. {  
    16.     if (std::is_pod<A>::value)  
    17.     {  
    18.         std::cout << "before" << std::endl;  
    19.         A a;  
    20.         a.x = 8;  
    21.         a.y = 10.5;  
    22.         std::cout << a.x << std::endl;  
    23.         std::cout << a.y << std::endl;  
    24.   
    25.         size_t size = sizeof(a);  
    26.         char *p = new char[size];  
    27.         memcpy(p, &a, size);  
    28.         A *pA = (A*)p;  
    29.   
    30.         std::cout << "after" << std::endl;  
    31.         std::cout << pA->x << std::endl;  
    32.         std::cout << pA->y << std::endl;  
    33.   
    34.         delete p;  
    35.     }  
    36.   
    37.     system("pause");  
    38.     return 0;  
    39. }  


    运行结果




    可以看到,对一个POD类型进行二进制拷贝后,数据都成功的迁移过来了。


  • 相关阅读:
    Codeforces 691A Fashion in Berland
    HDU 5741 Helter Skelter
    HDU 5735 Born Slippy
    HDU 5739 Fantasia
    HDU 5738 Eureka
    HDU 5734 Acperience
    HDU 5742 It's All In The Mind
    POJ Euro Efficiency 1252
    AtCoder Beginner Contest 067 C
    AtCoder Beginner Contest 067 D
  • 原文地址:https://www.cnblogs.com/zhoug2020/p/6111166.html
Copyright © 2011-2022 走看看