是否有一个有效的用例,其中非POD结构优先于类?

时间:2012-02-24 01:48:44

标签: c++ class struct language-history

根据(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等价物)?

2 个答案:

答案 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 ++通用性从一开始就存在。