在我的C ++项目中,有一个类需要创建一个对象数组。 在类的不同实例之间,数组的大小将不同,这就是我选择使用数组的原因。
如果我这样做:
int numberOfPlayers; // This is determined at run time.
int *players;
//In constructor
players= new int[numberOfPlayers]; // This works
但如果我这样做:
Character *players;
players = new Character[numberOfPlayers]; // Compiler complains
编译器抱怨"没有匹配的构造函数用于初始化Character"
如何动态声明类型"字符"。
的数组注意:角色与char无关。 Character是我自己创建的一个类的名称。
编辑:字符没有默认构造函数,因为它需要传递几个参数,因此可以使用正确的状态进行初始化。唯一的构造函数有几个参数。
编辑:我在一个向量上选择了一个动态创建的数组,因为我知道在实例的生命周期中,数组的大小将是常量,尽管在不同的实例之间,大小会有所不同。我认为这对性能原因(内存/速度)有意义。答案 0 :(得分:8)
“正确”的方式是使用std::vector
。它是一种快速,安全,更强大的替代恐怖new
。
std::vector<Character> vec;
vec.push_back(Character(params));
vec.push_back(Character(other_params));
如果您知道提前的大小,则可以使用std::vector::reserve
std::vector<Character> vec;
vec.reserve(50);
vec.push_back(Character(params));
vec.push_back(Character(other_params));
std::vector
的开销几乎不存在。
现在,你不能按照自己的方式做到这一点,这是因为默认情况下new
使用默认构造函数,它不存在。
答案 1 :(得分:4)
问题是您的类型Character
没有定义表单的默认构造函数:
Character::Character()
{
// etc.
}
答案 2 :(得分:3)
您的类型需要默认构造函数。与C malloc
不同,operator new
在分配时为您构造实例。然后它需要一个无参数(默认)构造函数,因为它无法传递参数。所以......
class Character
{
public:
Character(){}
};
答案 3 :(得分:3)
&#34;字符没有默认构造函数,因为它需要传递几个参数,因此可以使用正确的状态进行初始化。唯一的构造函数有几个参数&#34;
然后数组是错误的类型,因为数组总是默认构造其成员。
使用:
std::vector<Character> players;
大小可以根据需要变化,并且每个角色构建完成后你可以call players.push_back( character )
答案 4 :(得分:2)
简短的回答是,你不能这样做,因为标准不允许这样做。没有任何技术原因无法被允许 - 它只是不是。
一些编译器(例如gcc)多年来一直支持它作为C ++的扩展。它已经被各种编译器在C中支持了足够长的时间,C99对它进行了标准化,因此所有(当前合理的)C编译器现在都支持它。
有人提议添加类似数组的类,其大小在创建时确定,并在此之后保持不变,但委员会决定不接受 1 。只留下std::array
,这需要在编译时确定的大小,std::vector
,其大小可以在运行时动态变化。
但是,公平地说,如果您在创建矢量时知道矢量的大小,则可以在创建时指定矢量大小。虽然它仍然能够调整自身,但该功能主要在resize
和push_back
。如果您只是不使用它们,那么使用std::vector
与本机阵列相比的开销通常非常小,因此您不太可能从其他技术中获得显着收益(可能除外)在相当模糊的情况下)。
1.至少IMO,这是正确的决定 - 虽然我可以看到想法背后的基本推理,但我认为该提案存在足够的缺陷,以至于没有它我们会更好。 功能
答案 5 :(得分:1)
因为分配Character
数组意味着该数组将包含一定数量的Character
个实例。分配数组时,必须以某种方式初始化包含的每个实例,并且需要默认构造函数。
你必须声明Character::Character() { }
让编译器调用它。如果您不能提供默认构造函数,那么您应该考虑使用Character**
,以便您可以根据需要初始化它们,例如:
Character **array = new Character*[amount];
array[0] = new Character(...);
请注意,这需要删除每个实例,因此您需要
而不是delete[] array
for (int i = 0; i < amount; ++i)
delete array[i];
delete [] array;
另一种方法是忘记数组并使用std::vector
:
vector<Character> character;
character.push_back(Character(...));
这也可以减轻你自己管理记忆的需要。