我有几次遇到这个术语POD型。 这是什么意思?


#1楼

POD代表普通旧数据 - 即没有构造函数,析构函数和虚拟成员函数的类(无论是使用关键字struct还是关键字class )。 维基百科关于POD的文章更详细,并将其定义为:

C ++中的普通旧数据结构是一个聚合类,它只包含PODS作为成员,没有用户定义的析构函数,没有用户定义的复制赋值运算符,也没有指向成员类型的非静态成员。

在C ++ 98/03的答案中可以找到更多细节。 C ++ 11改变了围绕POD的规则,使它们大大放松,因此需要在此处进行后续回答 。


#2楼

普通旧数据

简而言之,它是所有内置数据类型(例如intcharfloatlongunsigned chardouble等)以及POD数据的所有聚合。 是的,这是一个递归定义。 ;)

更清楚一点,POD就是我们所说的“结构”:一个单元或一组只存储数据的单元。


#3楼

非正式地:

POD是一种类型(包括类),其中C ++编译器保证结构中不会出现“魔术”:例如,隐藏指向vtable的指针,在转换为其他类型时应用于地址的偏移量(至少如果目标的POD也是如此),构造函数或析构函数。 粗略地说,类型是POD,当它中的唯一内容是内置类型和它们的组合时。 结果是“像C”一样的行为。

不那么非正式:

  • intcharwchar_tboolfloatdouble是POD,以及它们的long/short和有signed/unsigned版本。
  • 指针(包括指向函数的指针和指向成员的指针)是POD,
  • enums是POD
  • constvolatile POD是POD。
  • POD的classstructunion是POD,前提是所有非静态数据成员都是public ,并且它没有基类,也没有构造函数,析构函数或虚方法。 静态成员不会在此规则下停止某个POD。 此规则在C ++ 11中已更改,并且允许某些私有成员: 具有所有私有成员的类是否可以是POD类?
  • 维基百科说POD不能包含指向成员的类型成员是错误的。 或者更确切地说,它对于C ++ 98的措辞是正确的,但TC1明确指出成员指针是POD。

形式上(C ++ 03标准):

3.9(10): “算术类型(3.9.1),枚举类型,指针类型和指向成员类型的指针(3.9.2)以及这些类型的cv限定版本(3.9.3)是统一调用者标量类型。标量类型,POD结构类型,POD联合类型(第9节),这些类型的数组和这些类型的cv限定版本(3.9.3)统称为POD类型“

9(4): “POD-struct是一个聚合类,它没有非POD-struct类型的非静态数据成员,非POD-union(或这类类型的数组)或引用,并且没有用户 -定义复制操作符,没有用户定义的析构函数。类似地,POD-union是一个聚合联合,它没有非POD-struct,非POD-union(或这类类型的数组)或引用类型的非静态数据成员,并且没有用户定义的复制操作符,也没有用户定义的析构函数。

8.5.1(1): “聚合是一个数组或类(第9节),没有用户声明的构造函数(12.1),没有私有或受保护的非静态数据成员(第11节),没有基类(第10节)没有虚拟功能(10.3)。“


#4楼

使用C ++,Plain Old Data并不仅仅意味着像int,char等这样的东西是唯一使用的类型。 普通的旧数据在实践中确实意味着你可以将一个struct memcpy从内存中的一个位置转移到另一个位置,并且事情将完全像你期望的那样工作(即不会爆炸)。 如果您的类或您的类包含的任何类具有作为指针或引用的成员或具有虚函数的类,则会中断。 从本质上讲,如果指针必须涉及到某个地方,那么它不是普通的旧数据。


#5楼

据我所知,POD(PlainOldData)只是一个原始数据 - 它不需要:

  • 要建造,
  • 要被摧毁
  • 有自定义运营商。
  • 一定不能有虚函数
  • 并且不得覆盖运营商。

如何检查某些东西是否是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)>{ };
}

(来自header type_traits)

参考:

  • http://en.cppreference.com/w/cpp/types/is_pod
  • http://en.wikipedia.org/wiki/Plain_old_data_structure
  • http://en.wikipedia.org/wiki/Plain_Old_C++_Object
  • 文件type_traits

#6楼

POD(普通旧数据)对象具有以下数据类型之一 - 基本类型,指针,联合,结构,数组或类 - 没有构造函数。 相反,非POD对象是构造函数所在的对象。 POD对象在获得具有适当大小的存储的类型时开始其生命周期,并且当对象的存储被重用或取消分配时,其生命周期结束。

PlainOldData类型也不能包含以下任何内容:

  • 虚函数(自己的或继承的)
  • 虚拟基类(直接或间接)。

PlainOldData的更宽松定义包括具有构造函数的对象; 但不包括虚拟的东西。 PlainOldData类型的重要问题是它们是非多态的。 可以使用POD类型进行继承,但是只应该对ImplementationInheritance(代码重用)而不是多态/子类型进行继承。

一个常见的(虽然不是严格正确的)定义是PlainOldData类型是没有VeeTable的任何东西。


#7楼

POD的概念和类型trait std::is_pod将在C ++ 20中弃用。 有关详细信息,请参阅此问题。


#8楼

使用C ++ 11到C ++ 17中的static_assert和POD效果的所有非POD案例的示例

std::is_pod是在C ++ 11中添加的,所以我们std::is_pod考虑这个标准。

std::is_pod将从https://stackoverflow.com/a/48435532/895245中提到的C ++ 20中删除,让我们在支持到达替换时更新它。

随着标准的发展,POD限制变得越来越宽松,我的目标是通过ifdef覆盖示例中的所有放松。

libstdc ++只需进行一些测试: https : //github.com/gcc-mirror/gcc/blob/gcc-8_2_0-release/libstdc%2B%2B-v3/testsuite/20_util/is_pod/value.cc但它太少了。 维护者:如果您阅读此帖,请合并。 我懒得查看上面提到的所有C ++测试项目: https : //softwareengineering.stackexchange.com/questions/199708/is-there-a-compliance-test-for-c-compilers

#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 >= 201103Lstatic_assert(std::is_pod<C>(), "");
#elsestatic_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-podstatic_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
}

GitHub上游 。

经测试:

for std in 11 14 17; do echo $std; g++-8 -Wall -Werror -Wextra -pedantic -std=c++$std pod.cpp; done

在Ubuntu 18.04,GCC 8.2.0上。


#9楼

为什么我们需要区分POD和非POD?

C ++作为C的扩展开始了它的生命。虽然现代C ++不再是C的严格超集,人们仍然希望两者之间具有高度的兼容性。

粗略地说,POD类型是与C兼容的类型,并且可能同样重要的是与某些ABI优化兼容。

为了与C兼容,我们需要满足两个约束。

  1. 布局必须与相应的C类型相同。
  2. 必须以与相应C类型相同的方式将类型传递给函数并从函数返回。

某些C ++功能与此不兼容。

虚方法要求编译器插入一个或多个指向虚方法表的指针,这些指针在C中不存在。

用户定义的复制构造函数,移动构造函数,复制赋值和析构函数对参数传递和返回有影响。 许多C ABI在寄存器中传递和返回小参数,但传递给用户定义的构造函数/ assigment /析构函数的引用只能用于内存位置。

因此需要定义哪些类型可以预期为“C兼容”,哪些类型不能。 在这方面,C ++ 03有点严格。 C ++ 11打开了很多东西。

C ++中的POD类型是什么?相关推荐

  1. 【C/C++ POD 类型】深度解析C++中的POD类型:从理论基础到项目实践

    深度解析C++中的POD类型:从理论基础到项目实践 1. C++中的POD类型(Plain Old Data) 1.1 POD类型的定义和特性 Trivial类型 Standard layout类型 ...

  2. c++中的pod类型

    最早看到POD(plain old data)类型,是在imperfect c++里.我觉得这是一本把我带到c++世界里的一本很重要的书. 书里是这样解释POD的: 1.   所有标量类型(基本类型和 ...

  3. C++11中的POD和Trivial

    引子 在介绍C++11的文章或者博客中,经常会出现POD类型和Trivial类型的影子.但是POD类型和Trivial类型到底是什么意思呢? POD类型 POD类型的好处 POD类型 粗略上来讲,PO ...

  4. C++中的trivial和non-trivial构造/析构/拷贝/赋值函数及POD类型

    在侯捷的<STL源码剖析>里提到trivial和non-trivial及POD类型,相关知识整理如下. trivial意思是无意义,这个trivial和non-trivial是对类的四种函 ...

  5. C++ 11 中的POD

    POD 是英文中Plain Old Data 的缩写,意如其名. Plain 表示了POD 是普通的类型, C++中常见的类型都是这样的属性,而不像一些存在着虚函数虚继承的类型那么特别. Old 则体 ...

  6. Kubernetes 中创建 Pod 时集群中到底发生了些什么?

    想象一下,如果我想将 nginx 部署到 Kubernetes 集群,我可能会在终端中输入类似这样的命令: $ kubectl run --image=nginx --replicas=3 然后回车. ...

  7. C++11 POD类型

    POD,全称plain old data,plain代表它是一个普通类型,old代表它可以与c兼容,可以使用比如memcpy()这类c中最原始函数进行操作.C++11中把POD分为了两个基本概念的集合 ...

  8. C++11的POD类型

    POD类型的定义 必须是平凡的和有标准布局的. 平凡的构造函数与析构函数是默认的,不起任何作用的.如果自定义了,那么需要声明为default类型的. 使用std::is_trivial进行判别. 标准 ...

  9. dns提供商主机名_在 Kubernetes 中使用 DNS 和 Headless Service 发现运行中的 Pod

    作者:Mattias te Wierik 翻译:Bach(才云) 校对:星空下的文仔(才云).bot(才云) 在 Kubernetes 集群中,Service 是将运行在一组 Pods 上的应用程序公 ...

最新文章

  1. 部署testlink报错,安装wampserver时提示丢失MSVCR110.dll
  2. mysql自增id用完了_MySQL表自增id用完了该怎么办?
  3. python3解析库BeautifulSoup4
  4. 在angular2项目里使用ng-zorro的icon
  5. mysql d是什么意思_是mysqld意思
  6. 【C++】交通咨询系统(最短路径问题)
  7. C++ Primer 第四章学习 —— “表达式”
  8. 开发一款游戏引擎所需要的知识与技术
  9. pytorch:线性回归实战
  10. 贪心题集(vjoj)
  11. STM32F103C8T6基础开发教程(HAL库)—点亮第一颗LED灯
  12. HTML5中canvas实现拼图游戏,HTML5 Canvas学习笔记(6)拼图游戏(数字版)
  13. (二)使用数组长度实现ADT bag(java)
  14. 随谈——那些前端的事1:关于坚持1
  15. 虎年起点:两个100万
  16. python pdb调试
  17. 次世代PBR游戏模型流程到底是怎么样?
  18. Launcher2 快捷方式图标的圆角处理及解析
  19. STM32 库函数学习 TIM篇
  20. JAVA虚拟机(JVM)划重点 第一章 走近Java

热门文章

  1. Android 自定义光标样式
  2. 【剑指offer-Java版】35第一个只出现一次的字符
  3. 教你如何 构建基本的用户控件
  4. 【git】几大区概念
  5. pcie转sata3硬盘不启动_没有地方塞硬盘?你或许需要这款扩展卡
  6. python软件在下载库文件_python – 并行下载多个文件的库或工具
  7. macOs下全局安装npm包的设置问题
  8. Python - 3.6 学习三
  9. 测试用例实例--常见功能测试点(转)
  10. jboss5+EJB3+MDB Queue