我有一个这样的课:
小片1:
struct B
{
int member;
// more complex members e.g. arrays of structs etc
};
这个类在代码中使用,假设它是一个C风格的结构(例如在memcpy,memset等中使用)
作为良好的编程原则的一部分,我正在考虑修改B,如下所示:
片段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
> std :: is_pod:false
> std :: is_trivial:false
> std :: is_trivially_copyable:true
> std :: is_trivial:false
扩展,我也会遵循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
> std :: is_pod:false
> std :: is_trivial:false
> std :: is_trivially_copyable:false
> std :: is_trivial:false
我需要了解在片段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的反应似乎表明琐事是必要的标准
最佳答案 如果您的结构只包含POD数据成员,并且不负责管理任何资源,例如动态分配的内存,那么绝对没有理由定义析构函数,复制构造函数和赋值运算符.最多我会添加一个构造函数来初始化数据成员.使用C 11,可以使用非静态数据成员初始值设定器轻松完成.
struct B
{
int member = 0; // this will initialize the data member to 0
};
您还可以添加一个带有int的构造函数,并允许您将成员初始化为任何所需的值.在这种情况下
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
};
这是一个坏主意,因为它没有添加对类有用的任何东西,并且使它变得非常简单,因为它现在有一个非平凡的默认构造函数.如果您确实要定义默认构造函数,则应该显式默认它.
struct B
{
B() = default;
int member;
// more complex members e.g. arrays of structs etc
};
这使得该类具有琐碎和标准的布局,允许您将其与C样式函数一起使用.