如何创建一个动态分配的对象数组且不使用默认构造函数?

4
动态创建的对象数组需要使用非默认构造函数,我遇到的问题是语法方面的。在我的想法中,我能够做到这一点的事实是
int * somePtr = new int[5];

这意味着我应该能够做到这一点。

IntegerSet* someSet = new IntegerSet(this->getLength())[5];

其中IntegerSet是我创建的一个代表整数集合的类。这段代码在IntegerSets的一个成员函数内部执行。当我尝试运行它时,我收到一个语法错误:"无法将IntegerSet转换为IntegerSet*"

我理解这意味着这两种类型不等效,但是除了第二部分必须传递构造函数参数列表之外,我看不出在执行第一部分和第二部分时有什么区别。因此,在代码的那一部分,我怀疑我语法有误。


1
以前通常情况下你不能这样做,要么你必须有一个默认构造函数以便动态分配对象数组,要么你必须使用放置 new 来将分配与构造分开。但是这在 C++11 中可能已经改变了。你正在使用哪个版本的 C++? - john
1
在C++中,使用std::vector比动态数组更方便(因为它更加便利),你可以看一下这个教程。 - Martin
@john 我正在使用 C++11 和 Visual Studio 2012专业版。问题是我需要动态分配一个数组来保存集合的成员,并且这个数组的长度基于用户设定的集合大小,所以我无法在没有调用默认构造函数的情况下分配 IntegerSets 数组,否则用户将无法传入变量长度。 - JohnA
听起来好像你对向量很满意 ;) - Martin
@Martin 我肯定想使用向量,我倾向于经常使用它们,但现在我们正在讲解动态内存分配。这个特定的任务并不是必需的(我问过我的老师关于语法,她也不知道),但我正在尝试添加一些额外的功能,使课程更有趣。 - JohnA
问题是:int 是一种类型,而 new IntegerSet(this->getLength()) 不是。数组创建只适用于类型。其他任何东西都被视为元素访问。 - thriqon
2个回答

3
new表达式只允许默认初始化,你不能在单个new表达式中完成此操作。你可以分配原始内存,并使用放置new一个接一个地构造对象(参见这个答案中的Object array initialization without default constructor)。

或者更好的方法是,不要使用C风格的数组。相反,使用一些STL容器,例如std::vector和它的构造函数,其中第二个参数是用于初始化元素的值:

std::vector<IntegerSet> integers(5, IntegerSet(this->getLength()) );

不行,因为这样整数集合数组会使用默认构造函数创建。我将this->getLength()作为参数传递给我创建的构造函数,这使得我创建的整数集合与调用该成员函数的整数集合长度相同。 - JohnA
他在问题开头说:“动态创建的对象数组需要使用非默认构造函数”。 - john
@user2813824:抱歉,我第一次误读了问题。请看我的编辑。 - LihO
@Liho,感谢提供链接和帮助。既然我知道这是不可能的,那我就使用一个向量,虽然这个函数对于这个项目并不是必要的,但我想添加一些功能,真正将动态对象分配推向极限。向量将会发挥作用! - JohnA

0

这个问题有一个简单的解决方法:在 IntegerSet 中添加一个默认构造函数,它不会获取内存和任何其他资源。这样,您就可以使用 new 分配一个 IntegerSet 数组,然后在下一步中填充数组的每个元素。

更好的解决方案是:使用 std::vector<IntegerSet>emplace_back() 使用非默认构造函数初始化数组的每个元素。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接