我得到了POD的含义,我知道当我在C ++中声明一个结构时
struct f {};
有一个默认构造函数,一个默认的复制构造函数,一个默认的析构函数等。(如果我得到了正确的话)
我的问题是:如何在没有隐式构造函数/析构函数等的情况下使用纯数据(如4个int值)声明POD结构。阻碍?
我错过了什么吗?
答案 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
。
同样重要的是要注意,成员函数不会作为成员变量存储在对象上。您可以同时将class
或struct
视为两件事:
数据布局的描述
包含用于操作该数据的函数和类型的名称空间
面向对象编程的C ++模型简单地将这两种东西结合在一起。
答案 1 :(得分:5)
如何在没有隐式构造函数/析构函数/等的情况下,使用纯数据(如4个int值)声明POD结构。阻碍?
像这样:
struct f {
int i1, i2, i3, i4;
};
编译器生成的构造函数不会妨碍它成为POD。
10)POD结构 109 是一个非联合类,既是一个普通类,又是一个标准布局类,并且没有 非POD结构类型的非静态数据成员,非POD联合(或此类型的数组)。同样,a POD union是一个简单的类和标准布局类的联合,并且没有非静态数据 非POD结构类型的成员,非POD联合(或此类型的数组)。 POD类是一个类 POD结构或POD联合。
所以,它必须是
a)一个琐碎的班级和 b)标准布局类。
如下所述:
7)标准布局类是一个类:
- 没有类型为非标准布局类(或此类类型的数组)或引用的非静态数据成员,
- 没有虚函数(10.3),没有虚基类(10.1),
- 对所有非静态数据成员具有相同的访问控制(第11条),
- 没有非标准布局基类,
- 要么在派生类最多的类中没有非静态数据成员,要么最多只有一个带有
的基类 非静态数据成员,或没有具有非静态数据成员的基类,以及
- 没有与第一个非静态数据成员相同类型的基类。
和
6)[...]一个普通的类是一个具有普通默认构造函数(12.1)并且可以轻易复制的类
详细信息:
5)[...] 如果默认构造函数不是用户提供的,则默认构造函数是微不足道的,如果: - 它的类没有虚函数(10.3),没有虚基类(10.1)和
- 其类的非静态数据成员没有括号或等于初始化程序,以及
- 其类的所有直接基类都有简单的默认构造函数和
- 对于类类的所有非静态数据成员(或其数组),每个这样的类 有一个普通的默认构造函数。
由于上述所有条件均适用,因此该课程为POD。
答案 2 :(得分:2)
首先,所有这些隐式成员函数仅在概念上存在。在你真正尝试使用它们之前,它们并没有真正影响任何东西。这意味着如果你不想要它们,它们不应该“妨碍”。
其次,非虚拟成员函数(无论是否显式声明)都不会影响类的数据布局。即在这方面,他们并没有“妨碍”(如果这就是你的意思)。
答案 3 :(得分:1)
是的,POD的定义明确排除了隐式生成的特殊成员函数。如果您指定其中一个完全与默认生成的相同,则会变得更加棘手:您的类型不再是POD。在C ++ 11中,使用default
关键字解决了这个问题。
有了这一切,POD的定义(通常)就像在C代码中一样:
struct X { int a, b, c, d; };