默认构造函数和POD

时间:2012-10-19 17:38:47

标签: c++

我得到了POD的含义,我知道当我在C ++中声明一个结构时

struct f {};

有一个默认构造函数,一个默认的复制构造函数,一个默认的析构函数等。(如果我得到了正确的话)

我的问题是:如何在没有隐式构造函数/析构函数等的情况下使用纯数据(如4个int值)声明POD结构。阻碍?

我错过了什么吗?

4 个答案:

答案 0 :(得分:7)

每个对象类型都有一个构造函数 - 否则你将如何构造它? - 和析构函数 - 否则它将如何被销毁?他们不会“妨碍”任何事情,因为默认实现在POD-only字段的情况下是no-ops,就像你说过的那样:

struct f {
    f() {}
    ~f() {}
    int a, b, c, d;
};

但是,如果编写一个空构造函数,则该类型将变为非POD。 C ++ 11通过默认解决了这个问题:

f() = default;
~f() = default;

复制构造函数的情况略有不同,其中隐式生成的只是为POD类型做“正确的事情”的便利:

f(const f& other) : a(other.a), b(other.b), c(other.c), d(other.d) {}

没有理由自己重写。如果要使类型为不可复制,可以使用f(const f&) = delete;将复制构造函数标记为已删除,或将其声明为private

同样重要的是要注意,成员函数不会作为成员变量存储在对象上。您可以同时将classstruct视为两件事:

  1. 数据布局的描述

  2. 包含用于操作该数据的函数和类型的名称空间

  3. 面向对象编程的C ++模型简单地将这两种东西结合在一起。

答案 1 :(得分:5)

  

如何在没有隐式构造函数/析构函数/等的情况下,使用纯数据(如4个int值)声明POD结构。阻碍?

像这样:

struct f {
  int i1, i2, i3, i4;
};

编译器生成的构造函数不会妨碍它成为POD。

9个类[class]

  

10)POD结构 109 是一个非联合类,既是一个普通类,又是一个标准布局类,并且没有   非POD结构类型的非静态数据成员,非POD联合(或此类型的数组)。同样,a   POD union是一个简单的类和标准布局类的联合,并且没有非静态数据   非POD结构类型的成员,非POD联合(或此类型的数组)。 POD类是一个类   POD结构或POD联合。

所以,它必须是

a)一个琐碎的班级和 b)标准布局类。

如下所述:

  

7)标准布局类是一个类:
   - 没有类型为非标准布局类(或此类类型的数组)或引用的非静态数据成员,
   - 没有虚函数(10.3),没有虚基类(10.1),
   - 对所有非静态数据成员具有相同的访问控制(第11条),
   - 没有非标准布局基类,
   - 要么在派生类最多的类中没有非静态数据成员,要么最多只有一个带有
的基类   非静态数据成员,或没有具有非静态数据成员的基类,以及
   - 没有与第一个非静态数据成员相同类型的基类。

  

6)[...]一个普通的类是一个具有普通默认构造函数(12.1)并且可以轻易复制的类

详细信息:

12.1构造函数[class.ctor]

  

5)[...] 如果默认构造函数不是用户提供的,则默认构造函数是微不足道的,如果:    - 它的类没有虚函数(10.3),没有虚基类(10.1)和
   - 其类的非静态数据成员没有括号或等于初始化程序,以及
   - 其类的所有直接基类都有简单的默认构造函数和
   - 对于类类的所有非静态数据成员(或其数组),每个这样的类   有一个普通的默认构造函数。

由于上述所有条件均适用,因此该课程为POD。

答案 2 :(得分:2)

首先,所有这些隐式成员函数仅在概念上存在。在你真正尝试使用它们之前,它们并没有真正影响任何东西。这意味着如果你不想要它们,它们不应该“妨碍”。

其次,非虚拟成员函数(无论是否显式声明)都不会影响类的数据布局。即在这方面,他们并没有“妨碍”(如果这就是你的意思)。

答案 3 :(得分:1)

是的,POD的定义明确排除了隐式生成的特殊成员函数。如果您指定其中一个完全与默认生成的相同,则会变得更加棘手:您的类型不再是POD。在C ++ 11中,使用default关键字解决了这个问题。

有了这一切,POD的定义(通常)就像在C代码中一样:

struct X { int a, b, c, d; };