根据(2003)标准的结构定义,它是一个类的特殊情况,具有成员,函数和基类的不同默认访问修饰符。它还继续将结构的要求定义为POD结构。
C ++ 2003 Standard,ISO 14882 Section 9.0.4:
结构是使用class-key结构定义的类;其成员和基类(第10条)是公开的 默认情况下(第11条)。 union是一个用class-key union定义的类;其成员是公开的 默认值,它一次只保存一个数据成员(9.5)。 [注意:类型的聚合在中描述 8.5.1。 POD-struct是一个聚合类,它没有非POD-struct类型的非静态数据成员, 非POD-union(或此类型的数组)或引用,并且没有用户定义的副本赋值运算符 并且没有用户定义的析构函数。类似地,POD-union是一个没有非静态数据的聚合联合 类型为非POD结构,非POD联合(或此类类型的数组)或引用的成员,并且没有用户定义 复制赋值运算符,没有用户定义的析构函数。 POD类是一个类 POD-struct或POD-union。
根据这个定义,非POD结构和类之间唯一的区别因素是默认访问修饰符。
这是我可以想象的具有非POD结构的目的:
public:
。当非POD结构被假定为其他系统的POD时会导致疼痛,例如当传递到C并返回时。为了说明,this person ran into problems when a struct that was assumed to be POD was updated by another developer such that it was no longer POD。因为默认情况下编译器不会静态声明POD-ness,所以当在仅可以使用POD结构的上下文中使用该结构时,应用程序将在运行时崩溃。更糟糕的是,我可以想象(虽然我不确定这是否可能)非POD结构在某些需要POD的情况下工作,而在其他情况下失败,导致错误和崩溃,这些都是艰难的追查。
看到有非POD结构可能导致奇怪和破碎行为的情况,非POD结构的用途是什么?为什么在编译时没有为POD-ness静态检查结构(通过C ++ 11中的std :: is_pod或Boost等价物)?
答案 0 :(得分:4)
我认为这是一个毫无意义的历史事故,坦白说,class
关键字永远不应该在C ++中添加。哦,好吧!
如果struct
被要求成为POD通常会很烦人 - 你经常从POD开始,只是因为你可以把它称为“结构”,然后最后不得不改变当你决定把它变成非POD时,它会在很多地方出现。
请注意,GCC(至少直到最近)并不关心你是否(转发)在某个地方将某个东西声明为某个类,而在其他地方将其声明为结构,反之亦然。 Clang抱怨这种事情(因为它有权利,尽管这会“破坏”一些现有的代码)。
答案 1 :(得分:0)
“编译器默认情况下不会静态声明POD-ness”
哦?
#include <iostream> // std::cout, std::endl
#include <type_traits> // std::is_pod
#include <string> // std::string, std::to_string
using namespace std;
struct A
{
int x;
};
struct B
{
string s;
};
int main()
{
static bool const a = is_pod<A>::value;
static_assert( a, "Ah..." );
static_assert( !is_pod<B>::value, "Bah!" );
}
允许struct
为非POD的原因,例如上面的B
,即为什么语言是这样设计的,可能在Bjarne Stroustrup的书“C ++的设计和演变”中找到。如果没有,那么可能只有Bjarne自己知道。因为struct
的这种C ++通用性从一开始就存在。