C ++在容器中的初始化与在本地变量中的初始化不同

问题描述

当我尝试为OpenGL缓冲区对象编写RAII包装器类时,出现了这个问题。 OpenGL创建缓冲区对象的方式是通过调用void glGenBuffers(GLsizei n​,GLuint* buffers​)来实现,该调用“返回n中的buffers​个缓冲区对象名称。”另外,请注意,对象名称0对于OpenGL是特殊的,它是认值"like a NULL pointer."

所以我的第一个想法是创建一个像{p1

buffer_object

我想要两种不同的初始化行为:

  • 如果我创建数组class buffer_object { public: // constructors,destructor private: unsigned int const name; }; ,我希望std::array<buffer_object,N> buffer_obj_array {};数组元素的buffer_object初始化为0。其他容器也是如此。
  • 如果我创建一个局部变量,请不要初始化为0,而是通过调用name来给它起一个名字。

问题是我不完全了解列表初始化,值初始化和认初始化。

关于glGenBuffers(1,&name)认构造函数,cppreference.com说它使用聚合初始化,这是列表初始化的一种,该值初始化数组中初始化列表中未提供的元素。关于值初始化,请访问cppreference.com says

如果T是具有至少一个用户提供的构造函数的类类型 任何类型的认构造函数都称为

那么,这是否意味着无法执行以下操作?

std::array

-因为我要从认构造函数中请求两种不同的行为?

也许我采用了错误方法

解决方法

C ++对象初始化不是也不能基于创建该对象的所在位置(除了琐碎类型的默认初始化对象外,该初始化对象在用于全局变量时为零初始化,但不适用于自动广告。

如果给一个类型一个非平凡的默认构造函数,则说明该类型的对象需要必须执行一些真实的代码,才能被认为是该类型的有效对象,这是一个强有力的声明。因此,C ++会假设您认真对待此声明,并确保在创建该类型的对象的所有情况下都执行所述“真实代码”。

如果为buffer_object提供了一个默认的构造函数,该构造函数生成一个缓冲区对象,则表示该类型的对象应始终拥有一个有效的OpenGL缓冲区对象(可能从其移出时除外)。如果为buffer_object提供了一个默认构造函数,该构造函数将内部缓冲区对象句柄清零,则表示没有OpenGL缓冲区对象句柄是buffer_object处于正常,有效的状态。

这两个陈述没有半途而废。默认值为空或不是。

现在,您可以具有备用构造函数了。默认构造函数可以使句柄为零,而另一个构造函数采用简单的标记类型,明确声明它将生成一个句柄。或更妙的是,工厂函数如何使buffer_object生成了句柄:

buffer_object gen_buffer()
{
  GLuint handle = 0;
  glGenBuffers(1,&handle);
  return buffer_object(handle);
};

auto obj = gen_buffer(); //Clearly states what is going on.

现在毫无疑问obj中有什么:它具有一个生成的缓冲区对象句柄。因为这就是代码所说的话。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...