我有一个类似的课程:
代码段1:
struct B
{
int member;
// more complex members e.g. arrays of structs etc
};
此类在代码中使用,假设它是C样式结构(例如,在 memcpy , memset 等中使用)
作为优秀编程原则的一部分,我正在考虑像这样修改B:
Snippet 2
struct B
{
B() {}
int member;
// more complex members e.g. arrays of structs etc
};
这是我的理解。如果我弄错了,请更正 一个。片段1定义B是POD,而片段2定义B不是POD,AND 湾在Snippet 2中,B仍然可以合法地用于C风格用途,例如memset和memcpy
扩展,我也会遵循Big 3(或者可能是Big 5)的规则,我会添加复制赋值以及复制构造函数。
摘录3:
struct B
{
B() {}
~B(){}
B& operator=(B &){ return *this; }
B(B const &r){}
int member;
// more complex members e.g. arrays of structs etc
};
这是我的理解。如果我弄错了,请更正 一个。在Snippet 3中,B现在不再合法地用于C风格用途,例如memset和memcpy
我需要了解在片段2和片段3中添加各种成员对B的C样式使用的影响。
C类的使用是否真的基于 is_trivially_copyable 或 is_trivial (这是更严格的限制)?
阅读$ 3.9 / 2告诉我,在C ++ 11中“is_trivially_copyable”确实是决定性标准。一些旧的C ++书籍(简而言之就是C ++)然而表明标准是关于POD与非POD的比较,我知道C ++ 11规则已经发生了变化。
Petes回应似乎表明琐碎是必要的标准
答案 0 :(得分:2)
如果你的结构只包含POD数据成员,并且不负责管理任何资源,例如动态分配的内存,那么绝对没有理由定义析构函数,复制构造函数和赋值运算符。最多我会添加一个构造函数来初始化数据成员。使用C ++ 11,可以使用非静态数据成员初始化器轻松完成。
struct B
{
int member = 0; // this will initialize the data member to 0
};
您还可以添加一个带int
的构造函数,并允许您将member
初始化为任何所需的值。在那种情况下
struct B
{
int member;
explicit B(int member = 0) : member(member) {}
};
这两项更改都将使您的班级可以轻易复制(9/6)和标准版面(9/7),这意味着您将能够使用他们有C风格的功能。
从评论中的讨论来看,似乎您不一定对初始化所有数据成员感兴趣,但仍希望提供默认构造函数。
struct B
{
B() {}
int member;
// more complex members e.g. arrays of structs etc
};
这是一个坏主意,因为它没有添加对类有用的任何东西,并且使它变得非常简单,因为它现在有一个非平凡的默认构造函数。如果您确实想要定义默认构造函数,则应该明确default
。
struct B
{
B() = default;
int member;
// more complex members e.g. arrays of structs etc
};
这使得该类具有琐碎和标准的布局,允许您将它与C样式函数一起使用。