是否存在非 POD 结构优于类的有效用例?
根据 (2003) 标准对结构的定义,它是类的特殊情况,对于成员、函数和基类具有不同的默认访问修饰符。它还继续定义结构成为 POD 结构的要求。
C++ 2003 标准,ISO 14882 第 9.0.4 节:
结构体是用类键结构体定义的类;它的成员和基类(第 10 条)是公共的 默认情况下(第 11 条)。联合是用类键联合定义的类;其成员是公开的 默认情况下,它一次只保存一个数据成员 (9.5)。 [注意:类类型的聚合在中描述 8.5.1. ] POD-struct 是一个聚合类,没有非 POD-struct 类型的非静态数据成员, 非 POD 联合(或此类类型的数组)或引用,并且没有用户定义的复制赋值运算符 并且没有用户定义的析构函数。类似地,POD 联合是没有非静态数据的聚合联合 非 POD 结构、非 POD 联合(或此类类型的数组)或引用类型的成员,并且没有用户定义的成员 复制赋值运算符并且没有用户定义的析构函数。 POD 类是一个类,它可以是 POD 结构或 POD 联合。
根据这个定义,非 POD 结构和类之间的唯一区别因素是默认访问修饰符。
以下是我可以想象的使用非 POD 结构的目的:
- 它们是一个遗留功能,需要维护以实现向后兼容性
- 键入
public:
很困难。
当其他系统假定非 POD 结构是 POD 时,例如当传递到 C 并返回时,非 POD 结构可能会导致麻烦。为了说明这一点,当假设的结构是POD 已被另一位开发人员更新,不再是 POD。由于默认情况下编译器不会静态断言 POD 性,因此当在只能使用 POD 结构的上下文中使用该结构时,应用程序将在运行时崩溃。更糟糕的是,我可以想象(尽管我不确定这是否可能)一个非 POD 结构在需要 POD 的某些情况下工作,而在其他情况下失败,导致错误和崩溃,这简直是难以想象的。追查。
鉴于在某些情况下使用非 POD 结构可能会导致奇怪和损坏的行为,那么非 POD 结构有什么用呢?为什么不在编译时静态检查结构体的 POD 性(通过 C++11 中的 std::is_pod 或 Boost 等效项)?
According to the (2003) standard's definition of a struct, it is a specialized case of a class, with different default access modifiers for members, functions, and base classes. It also goes on to define the requirements of a struct to be a POD-struct.
C++ 2003 Standard, ISO 14882 Section 9.0.4:
A structure is a class defined with the class-key struct; its members and base classes (clause 10) are public
by default (clause 11). A union is a class defined with the class-key union; its members are public by
default and it holds only one data member at a time (9.5). [Note: aggregates of class type are described in
8.5.1. ] A POD-struct is an aggregate class that has no non-static data members of type non-POD-struct,
non-POD-union (or array of such types) or reference, and has no user-defined copy assignment operator
and no user-defined destructor. Similarly, a POD-union is an aggregate union that has no non-static data
members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no userdefined
copy assignment operator and no user-defined destructor. A POD class is a class that is either a
POD-struct or a POD-union.
Given this definition, the only differentiating factor between a non-POD struct and a class is the default access modifier.
Here's what I could imagine as the purpose of having non-POD structs:
- They're a legacy feature that needs to be maintained for backwards-compatibility
- Typing
public:
is hard.
Having non-POD structs can lead to pain when they're assumed to be POD by other systems, for example when passed around to C and back. To illustrate, 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. Because POD-ness isn't statically asserted by the compiler by default, the application would crash at run-time when that struct was used in contexts where only POD structs could be used. Even worse, I could imagine (though I don't know for certain if this is possible) a non-POD struct working in certain circumstances that require POD, and failing in others, leading to errors and crashes that are nothing short of arduous to track down.
Seeing as there are situations where having non-POD structs can lead to the realm of bizarre and broken behavior, what is the use of non-POD structs? Why aren't structs statically checked for POD-ness at compile-time (via std::is_pod in C++11 or the Boost equivalent)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为这是一个毫无意义的历史事故,坦率地说,
class
关键字根本不应该添加到 C++ 中。那好吧!如果
struct
被要求是 POD,这通常会很烦人——您经常会从 POD 开始,只是因为可以将其称为“结构”,然后最终不得不更改稍后当您决定将其设为非 POD 时,它会在许多地方出现。请注意,GCC(至少直到最近)并不关心您是否(转发)在一个地方将某些内容声明为类并在其他地方声明为结构,反之亦然。 Clang 抱怨这类事情(因为它完全有权这样做,尽管这确实“破坏”了一些现有代码)。
I think it's a pointless historical accident, and frankly the
class
keyword never should have been added in C++ at all. Oh well!It would often be annoying if a
struct
was required to be POD--you'd often start out with something POD, call it a "struct" just because you could, and then wind up having to change it in many places later on when you decide to make it non-POD.Note that GCC (at least until recently) did not care if you (forward) declared something as a class in one place and as a struct elsewhere, or vice versa. Clang complains about this sort of thing (as it has every right to, though this does "break" some existing code).
哦?
struct
被允许是非 POD 的原因,如上面的B
,即为什么语言是这样设计的,可能是为了可以在 Bjarne Stroustrup 的书《C++ 的设计与演化》中找到。如果不是,那么可能只有 Bjarne 自己知道。因为struct
的这种 C++ 通用性从一开始就存在。Oh?
The reason that
struct
is allowed to be non-POD, as e.g.B
above, i.e. why the language is designed this way, is probably to be found in Bjarne Stroustrup’s book “The Design and Evolution of C++”. And if not, then probably only Bjarne himself knows. Because this C++ generality ofstruct
has been there since the very beginning.