0

我正在尝试创建一个类似于容器 Vector 的向量。

然后声明:

Vector< A> Avector.

在分配内存时,它会给出 A 没有默认构造函数的编译错误。我编写了以下代码来分配内存。

char *pBuffer = (char*) malloc(size*sizeof(T));
  T *array;
   for(int i = 0; i < size; i++)
  {
    (array+i) = new(pBuffer + i) T;
  }
  return array;

T 是一个模板变量。

该错误是由于在放置 new 时我使用了 T 的默认构造函数,而我没有为 A 编写默认构造函数。

我想知道,有没有办法让内存分配不依赖于构造函数签名。

4

2 回答 2

2

在 C++ 中,调用new做了两件事:

  1. 为正在创建的对象分配足够的内存 &
  2. 提供通过调用其构造函数正确初始化对象的机会。

这是 C++ 作为一门语言的基本设计特征,明显添加了 pt 2 以克服malloc仅分配内存的行为。

简而言之,您无法更改此行为。

于 2012-11-01T05:34:03.863 回答
1

这不是取决于构造函数签名的内存分配。这是初始化

即使在您的示例中,分配也是在malloc不调用任何构造函数的情况下执行的。它是需要使用构造函数的初始化(由placement-new 执行)。

如果不调用其构造函数,就无法初始化用户定义的对象。

但是,至少在 C++11 中,您可以做的是将代码放入一个函数中,该函数将构造函数所需的参数作为右值引用,并将它们传递给placement-new 中的构造函数调用. 这样,由函数的调用者来传递正确的参数。如果未传递任何参数,则将调用默认构造函数。

这实际上是new的emplace-style 函数std::vector使用的技术:

template< class... Args >
void emplace_back( Args&&... args );

它是一个可变参数模板,因此可以有任意数量的参数(零个或多个)。右值引用用于获取它们,并且在实现中您必须调用构造函数 usingstd::forward以确保按原样传递参数:

(array+i) = new (pBuffer + i) T(std::forward<Params>(args)...);

所以这仍然需要使用构造函数,但它让调用者选择构造函数(通过选择参数)。如果没有可用的默认构造函数,调用者只需提供调用非默认构造函数所需的参数。

于 2012-11-01T05:53:14.227 回答