当前位置:网站首页>Pod type

Pod type

2022-06-22 16:17:00 Ordinary people who like playing basketball

1.POD type

POD It's in English Plain Old Data Abbreviation , Which translates as Common old data .POD stay C++ Chinese is a very important concept , Usually used to describe properties of a type , Especially the properties of user-defined types .

POD Attribute in C++11 It is often to build other C++ The basis of the concept , in fact , stay C++11 In the standard ,POD The probability of occurrence is quite high .

  • Plain : The expression is a common type
  • Old : Reflects its C The compatibility of , Support standards C function

stay C++11 Lieutenant general POD Divided into a collection of two basic concepts , namely ∶ ordinary (trivial) And standard layout (standard layout ) .

2.“ ordinary ” type

A trivial class or structure should meet the following requirements :
(1) Have a trivial default constructor (trivial constructor) And destructors (trivial destructor).

  • A trivial default constructor means that the constructor does nothing .

  • Usually , Do not define the constructor of the class , The compiler will generate a trivial default constructor for us .

  • eg:

//  Use the default constructor 
class Test {
    };
  • Once the constructor is defined , Even if the constructor does not contain parameters , There is no code in the function body , Then the constructor is no longer " ordinary " Of .

  • eg: The destructors are also similar to the constructors listed above , Once defined, it is extraordinary . But this is not hopeless , Use =default Keyword can explicitly declare the default constructor , So that the type is restored “ Trivialization ”.

class Test1 
{
    
    Test1();	//  Constructor defined by the program ,  Non default construction 
};

(2) Have an ordinary copy constructor (trivial copy constructor) And mobile constructors (trivial move constructor).

  • A trivial copy constructor is basically equivalent to using memcpy Construct the type .
  • Just like the ordinary default constructor , Without declaring a copy constructor , The compiler will help the programmer automatically generate .
  • You can use... Explicitly = default Declare the default copy constructor .
  • The trivial move constructor is similar to the trivial copy constructor , Just for mobile semantics .

(3) Have trivial copy assignment operators (trivial assignment operator) And move assignment operators (trivial move operator)

  • This is basically similar to the trivial copy constructor and the trivial move constructor .

(4) It does not contain virtual functions and virtual base classes .

  • Class virtual Keyword decorated function It's called a virtual function
class Base 
{
    
public:
    Base() {
    }
    virtual void print() {
    }
};
  • The virtual base class is added before the inherited base class when creating a subclass virtual keyword modification
class Base 
{
    
public:
    Base() {
    }
    virtual void print() {
    }
};
  • eg:
class Base 
{
    
public:
    Base() {
    }
};
//  Subclass Child, virtual base class :Base
class Child : virtual public Base 
{
    
    Child() {
    }
};

3.“ Standard layout ” type

Standard layout types mainly refer to the structure or combination of classes or structures .

Classes of standard layout types should conform to the following five definitions , The most important are the first two :

(1) All non static members have the same Access rights of (public,private,protected).

  • Class members have different access rights ( Non standard layout type )
class Base
{
    
public:
    Base() {
    }
    int a;
protected:
    int b;
private:
    int c;
};
  • Class members have the same access rights ( Standard layout type )
class Base
{
    
public:
    Base() {
    }
    int a;
    int b;
    int c;
};

(2) When a class or structure inherits , Satisfy one of the following two situations ∶

  • The base class contains static members ( Or the base class has no variables ), There are non static members in derived classes .
  • Base classes have non static members , Derived classes have no non static members .
struct Base {
     static int a;};
struct Child: public Base{
     int b;};          // ok
struct Base1 {
     int a;};
struct Child1: public Base1{
     static int c;}; // ok
struct Child2:public Base, public Base1 {
     static int d;); // ok
struct Child3:public Base1{
     int d;};         // error
struct Child4:public Base1, public Child // error
{
    
    static int num;
};

The conclusion drawn from the above example :

  • As long as non static members appear between derived classes and base classes at the same time , That is, it does not belong to the standard layout .
  • For multiple inheritance , Once non static members appear in multiple base classes , Even if there are no non static member variables in the derived class , Derived classes also do not belong to the standard layout .

(3) The type of the first non static member in a subclass is different from its base class .

  • This is based on G++ Compiler explanation , If you use VS The compiler and G++ The compiler gets different results .
struct Parent{
    };
struct Child : public Parent
{
    
    Parent p;	//  The first non static member of a subclass 
    int foo;
};
  • In the example above Child Not a standard layout type **, Because its first non static member variable p The same type as the parent class **, Change to the following, and the class becomes a standard layout type :
struct Parent{
    };
struct Child1 : public Parent
{
    
    int foo;   //  The first non static member of a subclass 
    Parent p;	
};

This rule is special for us , The main purpose of this provision is to save memory , Improve the efficiency of data reading .

  • For the above two subclasses Child and Child1 Their memory structures are different , When the base class has no members
  • C++ Standard allows standard layout types (Child1) The first member of a derived class foo Share address with base class , At this point, the base class does not occupy any real space ( Can save a little data )
  • For subclasses Child for , If the first member of the subclass is still the base class type ,C++ The standard requires that objects of the same type have different addresses ( A base class address cannot be associated with a variable in a subclass p The same type ), At this point, you need to allocate additional address space to stagger the addresses of the two .
     Insert picture description here
    (3) There are no virtual functions and virtual base classes .
    (4) All non static data members conform to the standard layout type , Its base class also conforms to the standard layout , This is a recursive definition .

4. Yes “ ordinary ” Type judgment

If we want to judge whether a data type belongs to POD type , have access to C++11 The related functions provided to us :

Yes “ ordinary ” Type judgment

  • C++11 The provided class template is called is_trivial, Its definition is as follows :
template <class T> struct std::is_trivial;
  • std::is_trivial Members of value Can be used to judge T Whether the type of is an ordinary type (value The return value of the function is Boolean ).
  • In addition to classes and structures ,is_trivial You can also use the built-in standard type data ( such as int、float All belong to ordinary types ) And array types ( Arrays whose elements are trivial types are always trivial ) Judge .
  • eg:
#include <iostream>
#include <type_traits>
using namespace std;

class A {
    };
class B {
     B() {
    } };
class C : B {
    };
class D {
     virtual void fn() {
    } };
class E : virtual public A {
     };

int main() 
{
    
//boolalpha  It's a header file #include <iostream>  Medium   A function , It's a bo ol  Type variable according to true or false  Of 
    cout << std::boolalpha;
    cout << "is_trivial:" << std::endl;
    // Built in standard data types , Belong to  trivial  type 
    cout << "int: " << is_trivial<int>::value << endl;
    // Have default constructors and destructors , Belong to  trivial  type 
    cout << "A: " << is_trivial<A>::value << endl;
    // Custom constructor , So it doesn't belong to  trivial  type 
    cout << "B: " << is_trivial<B>::value << endl;
    // The constructor is customized in the base class , So it doesn't belong to  trivial  type 
    cout << "C: " << is_trivial<C>::value << endl;
    // There are virtual functions in class member functions , So it doesn't belong to  trivial  type 
    cout << "D: " << is_trivial<D>::value << endl;
    // There is a virtual base class in the inheritance relationship , So it doesn't belong to  trivial  type 
    cout << "E: " << is_trivial<E>::value << endl;
    return 0;
}
  • test :
     Insert picture description here

5. Yes “ Standard layout ” Type judgment

Again , stay C++11 in , We can use template classes to help determine whether the type is a standard layout type ,

  • Its definition is as follows :
template <typename T> struct std::is_standard_layout;
  • adopt is_standard_layout Members of the template class value(is_standard_layout∶∶value), We can print out the standard layout properties of types in the code , The return value of the function is Boolean .
  • eg:
// pod.cpp
#include <iostream>
#include <type_traits>
using namespace std;

struct A {
     };
struct B : A {
     int j; };
struct C
{
    
public:
    int a;
private:
    int c;
};
struct D1 {
      static int i; };
struct D2 {
      int i; };
struct E1 {
     static int i; };
struct E2 {
     int i; };
struct D : public D1, public E1 {
     int a; };
struct E : public D1, public E2 {
     int a; };
struct F : public D2, public E2 {
     static int a; };
struct G : public A
{
    
    int foo;
    A a;
};
struct H : public A
{
    
    A a;
    int foo;
};

int main() 
{
    
    cout << std::boolalpha;
    cout << "is_standard_layout:" << std::endl;
    // There are no virtual base classes and virtual functions , Belong to  standard_layout  type 
    cout << "A: " << is_standard_layout<A>::value << endl;
    // There are no virtual base classes and virtual functions , Belong to  standard_layout  type 
    cout << "B: " << is_standard_layout<B>::value << endl;
    // Access permissions of all non static members are inconsistent , Do not belong to  standard_layout  type 
    cout << "C: " << is_standard_layout<C>::value << endl;
    // The base class and subclass do not have non static member variables at the same time , Belong to  standard_layout  type 
    cout << "D: " << is_standard_layout<D>::value << endl;
    // There are no virtual base classes and virtual functions , Belong to  standard_layout  type 
    cout << "D1: " << is_standard_layout<D1>::value << endl;
    // Non static member variables appear in both base class and subclass , Do not belong to  standard_layout  type 
    cout << "E: " << is_standard_layout<E>::value << endl;
    // In multiple inheritance, non static member variables appear in the base class at the same time , Do not belong to  standard_layout  type 
    cout << "F: " << is_standard_layout<F>::value << endl;
    // Different compilers are used , The results are different .
    cout << "G: " << is_standard_layout<G>::value << endl;
    // The type of the first non static member in a subclass cannot be the same as its base class type , Do not belong to  standard_layout  type 
    cout << "H: " << is_standard_layout<H>::value << endl;
    return 0;
}
  • test :vs test
     Insert picture description here
  • test : Use g++
     Insert picture description here

6. summary

in fact , Many of the built-in types we use are... By default POD Of .POD The most complicated part is the judgment of classes or structures .

that , Use POD What are the benefits ?

  • Byte assignment , In the code, we can safely use memset and memcpy Yes POD Type to initialize and copy .

  • Provide right C Memory layout compatible .C++ The program can work with C Functions interoperate , because POD Type of data in C And C++ The operation between is always safe .

  • It ensures the safety and effectiveness of static initialization . Static initialization can improve the performance of programs in many cases , and POD Initialization of objects of type is often simpler .

  • Reference resources :POD type

原网站

版权声明
本文为[Ordinary people who like playing basketball]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/173/202206221446593149.html