我正在尝试创建一个像容器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编写默认构造函数。
我想知道,有没有办法使内存分配不依赖于构造函数签名。
答案 0 :(得分:2)
在C ++中,调用new
会做两件事:
这是C ++作为一种语言的基本设计特性,为了克服仅分配内存的malloc
行为,pt 2被明显地添加。
简而言之,你无法改变这种行为。
答案 1 :(得分:1)
内存分配不依赖于构造函数签名。它是初始化。
即使在您的示例中,分配也由malloc
执行,而不调用任何构造函数。这是初始化(由placement-new执行),需要使用构造函数。
如果不调用其构造函数,则无法初始化用户定义的对象。
但是,至少在C ++ 11中,您可以做的是将代码放入一个函数中,该函数将构造函数所需的参数作为rvalue-references,并将它们传递给构造函数调用。放置新的。这样,你的函数调用者可以传递正确的参数。如果没有传递参数,则将调用默认构造函数。
这实际上是新std::vector
的{{3}}所使用的技术:
template< class... Args >
void emplace_back( Args&&... args );
它是一个可变参数模板,因此任何数量的参数(零或更多)都是可能的。 Rvalue-references用于获取它们,并且在实现中你必须使用std::forward
来调用构造函数以确保参数按原样传递:
(array+i) = new (pBuffer + i) T(std::forward<Params>(args)...);
所以这仍然需要使用构造函数,但是它让调用者选择构造函数(通过选择参数)。如果没有可用的默认构造函数,则调用者只需提供调用非默认构造函数所需的参数。