C++ C++;?
这个术语我已经见过好几次了。C++ C++;?,c++,types,c++-faq,C++,Types,C++ Faq,这个术语我已经见过好几次了。 这是什么意思 POD代表普通的旧数据-即一个类(无论是用关键字struct定义的还是用关键字class定义的),没有构造函数、析构函数和虚成员函数。更详细地介绍并将其定义为: C++中的一个简单的旧数据结构是一个聚合类,它只包含POD作为成员,没有用户定义的析构函数,没有用户定义的复制赋值操作符,也没有成员类型指针的非静态成员。 更多详细信息请参见。C++11改变了POD周围的规则,大大放松了它们。 简而言之,它是所有内置数据类型(例如,int,char,floa
这是什么意思 POD代表普通的旧数据-即一个类(无论是用关键字
struct
定义的还是用关键字class
定义的),没有构造函数、析构函数和虚成员函数。更详细地介绍并将其定义为:
C++中的一个简单的旧数据结构是一个聚合类,它只包含POD作为成员,没有用户定义的析构函数,没有用户定义的复制赋值操作符,也没有成员类型指针的非静态成员。 更多详细信息请参见。C++11改变了POD周围的规则,大大放松了它们。
简而言之,它是所有内置数据类型(例如,int
,char
,float
,long
,无符号char
,double
,等等)以及POD数据的所有聚合。是的,这是一个递归定义
更清楚地说,POD就是我们所说的“结构”:一个单元或一组单元,只存储数据。非常非正式:
一个POD是一种类型(包括类),其中C++编译器保证了结构中不会有“魔法”:例如,指向VTABLE的隐藏指针,当它被转换到其他类型(至少是目标的POD)时,应用到地址的偏移量,构造函数或析构函数。粗略地说,一个类型就是一个POD,其中只有内置类型及其组合。结果是“像”C类型的东西
非正式地说:
,int
,char
,wchar\u t
,bool
,float
是POD,长/短和double
版本也是POD有符号/无符号
- 指针(包括指向函数的指针和指向成员的指针)是POD
是PODenum
或const
POD是一个PODvolatile
- POD的
、class
或struct
是一个POD,前提是所有非静态数据成员都是union
,并且它没有基类,也没有构造函数、析构函数或虚方法。根据这条规则,静态成员不会阻止某些东西成为一个豆荚。此规则在C++11中已更改,允许某些私有成员:public
- 维基百科错误地说POD不能有指向成员的指针类型的成员。或者更确切地说,C++98的措辞是正确的,但TC1明确指出,指向成员的指针是POD
用C++,普通的旧数据并不意味着像int,char等的东西是唯一使用的类型。实际上,旧的数据实际上意味着你可以从内存中的一个位置把结构MMECPY从另一个位置移到另一个位置,事情会像你所期望的那样工作(即不被炸毁)。。如果您的类或您的类包含的任何类的成员是指针、引用或具有虚拟函数的类,则会出现这种情况。本质上,如果必须在某个位置涉及指针,则它不是纯旧数据。
据我所知,POD(纯旧数据)只是一个原始数据-它不需要:- 待建设,
- 被摧毁,
- 使用自定义运算符
- 不能有虚拟功能,
- 并且不能覆盖运算符
std::is_POD
:
namespace std {
// Could use is_standard_layout && is_trivial instead of the builtin.
template<typename _Tp>
struct is_pod
: public integral_constant<bool, __is_pod(_Tp)>
{ };
}
名称空间std{
//可以使用is_标准布局&is_普通而不是内置布局。
模板
结构是_pod
:公共积分常数
{ };
}
(来自标题类型_特征)
参考:
- 文件类型
- 虚拟函数(它们自己的或继承的)
- 虚拟基类(直接或间接)
一个常见的(虽然不是严格正确的)定义是,PlainOldData类型是没有VeeTable的任何东西。POD的概念和类型trait
std::is_POD
将是
#include <type_traits>
#include <array>
#include <vector>
int main() {
#if __cplusplus >= 201103L
// # Not POD
//
// Non-POD examples. Let's just walk all non-recursive non-POD branches of cppreference.
{
// Non-trivial implies non-POD.
// https://en.cppreference.com/w/cpp/named_req/TrivialType
{
// Has one or more default constructors, all of which are either
// trivial or deleted, and at least one of which is not deleted.
{
// Not trivial because we removed the default constructor
// by using our own custom non-default constructor.
{
struct C {
C(int) {}
};
static_assert(std::is_trivially_copyable<C>(), "");
static_assert(!std::is_trivial<C>(), "");
static_assert(!std::is_pod<C>(), "");
}
// No, this is not a default trivial constructor either:
// https://en.cppreference.com/w/cpp/language/default_constructor
//
// The constructor is not user-provided (i.e., is implicitly-defined or
// defaulted on its first declaration)
{
struct C {
C() {}
};
static_assert(std::is_trivially_copyable<C>(), "");
static_assert(!std::is_trivial<C>(), "");
static_assert(!std::is_pod<C>(), "");
}
}
// Not trivial because not trivially copyable.
{
struct C {
C(C&) {}
};
static_assert(!std::is_trivially_copyable<C>(), "");
static_assert(!std::is_trivial<C>(), "");
static_assert(!std::is_pod<C>(), "");
}
}
// Non-standard layout implies non-POD.
// https://en.cppreference.com/w/cpp/named_req/StandardLayoutType
{
// Non static members with different access control.
{
// i is public and j is private.
{
struct C {
public:
int i;
private:
int j;
};
static_assert(!std::is_standard_layout<C>(), "");
static_assert(!std::is_pod<C>(), "");
}
// These have the same access control.
{
struct C {
private:
int i;
int j;
};
static_assert(std::is_standard_layout<C>(), "");
static_assert(std::is_pod<C>(), "");
struct D {
public:
int i;
int j;
};
static_assert(std::is_standard_layout<D>(), "");
static_assert(std::is_pod<D>(), "");
}
}
// Virtual function.
{
struct C {
virtual void f() = 0;
};
static_assert(!std::is_standard_layout<C>(), "");
static_assert(!std::is_pod<C>(), "");
}
// Non-static member that is reference.
{
struct C {
int &i;
};
static_assert(!std::is_standard_layout<C>(), "");
static_assert(!std::is_pod<C>(), "");
}
// Neither:
//
// - has no base classes with non-static data members, or
// - has no non-static data members in the most derived class
// and at most one base class with non-static data members
{
// Non POD because has two base classes with non-static data members.
{
struct Base1 {
int i;
};
struct Base2 {
int j;
};
struct C : Base1, Base2 {};
static_assert(!std::is_standard_layout<C>(), "");
static_assert(!std::is_pod<C>(), "");
}
// POD: has just one base class with non-static member.
{
struct Base1 {
int i;
};
struct C : Base1 {};
static_assert(std::is_standard_layout<C>(), "");
static_assert(std::is_pod<C>(), "");
}
// Just one base class with non-static member: Base1, Base2 has none.
{
struct Base1 {
int i;
};
struct Base2 {};
struct C : Base1, Base2 {};
static_assert(std::is_standard_layout<C>(), "");
static_assert(std::is_pod<C>(), "");
}
}
// Base classes of the same type as the first non-static data member.
// TODO failing on GCC 8.1 -std=c++11, 14 and 17.
{
struct C {};
struct D : C {
C c;
};
//static_assert(!std::is_standard_layout<C>(), "");
//static_assert(!std::is_pod<C>(), "");
};
// C++14 standard layout new rules, yay!
{
// Has two (possibly indirect) base class subobjects of the same type.
// Here C has two base classes which are indirectly "Base".
//
// TODO failing on GCC 8.1 -std=c++11, 14 and 17.
// even though the example was copy pasted from cppreference.
{
struct Q {};
struct S : Q { };
struct T : Q { };
struct U : S, T { }; // not a standard-layout class: two base class subobjects of type Q
//static_assert(!std::is_standard_layout<U>(), "");
//static_assert(!std::is_pod<U>(), "");
}
// Has all non-static data members and bit-fields declared in the same class
// (either all in the derived or all in some base).
{
struct Base { int i; };
struct Middle : Base {};
struct C : Middle { int j; };
static_assert(!std::is_standard_layout<C>(), "");
static_assert(!std::is_pod<C>(), "");
}
// None of the base class subobjects has the same type as
// for non-union types, as the first non-static data member
//
// TODO: similar to the C++11 for which we could not make a proper example,
// but with recursivity added.
// TODO come up with an example that is POD in C++14 but not in C++11.
}
}
}
// # POD
//
// POD examples. Everything that does not fall neatly in the non-POD examples.
{
// Can't get more POD than this.
{
struct C {};
static_assert(std::is_pod<C>(), "");
static_assert(std::is_pod<int>(), "");
}
// Array of POD is POD.
{
struct C {};
static_assert(std::is_pod<C>(), "");
static_assert(std::is_pod<C[]>(), "");
}
// Private member: became POD in C++11
// https://stackoverflow.com/questions/4762788/can-a-class-with-all-private-members-be-a-pod-class/4762944#4762944
{
struct C {
private:
int i;
};
#if __cplusplus >= 201103L
static_assert(std::is_pod<C>(), "");
#else
static_assert(!std::is_pod<C>(), "");
#endif
}
// Most standard library containers are not POD because they are not trivial,
// which can be seen directly from their interface definition in the standard.
// https://stackoverflow.com/questions/27165436/pod-implications-for-a-struct-which-holds-an-standard-library-container
{
static_assert(!std::is_pod<std::vector<int>>(), "");
static_assert(!std::is_trivially_copyable<std::vector<int>>(), "");
// Some might be though:
// https://stackoverflow.com/questions/3674247/is-stdarrayt-s-guaranteed-to-be-pod-if-t-is-pod
static_assert(std::is_pod<std::array<int, 1>>(), "");
}
}
// # POD effects
//
// Now let's verify what effects does PODness have.
//
// Note that this is not easy to do automatically, since many of the
// failures are undefined behaviour.
//
// A good initial list can be found at:
// https://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/4178176#4178176
{
struct Pod {
uint32_t i;
uint64_t j;
};
static_assert(std::is_pod<Pod>(), "");
struct NotPod {
NotPod(uint32_t i, uint64_t j) : i(i), j(j) {}
uint32_t i;
uint64_t j;
};
static_assert(!std::is_pod<NotPod>(), "");
// __attribute__((packed)) only works for POD, and is ignored for non-POD, and emits a warning
// https://stackoverflow.com/questions/35152877/ignoring-packed-attribute-because-of-unpacked-non-pod-field/52986680#52986680
{
struct C {
int i;
};
struct D : C {
int j;
};
struct E {
D d;
} /*__attribute__((packed))*/;
static_assert(std::is_pod<C>(), "");
static_assert(!std::is_pod<D>(), "");
static_assert(!std::is_pod<E>(), "");
}
}
#endif
}
for std in 11 14 17; do echo $std; g++-8 -Wall -Werror -Wextra -pedantic -std=c++$std pod.cpp; done