C风格使用现代C类

我有一个这样的课:

小片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样式函数一起使用.

点赞