稍后调用 Class 构造函数创建 std::vector<Class>
Creating std::vector<Class> with calling Class constructor later on
我一直在谷歌搜索和 Whosebuging 这个问题,但找不到任何答案。
我想做的是创建一个带有自定义 class 的向量,我对此没有问题。我明白我需要做的:
std::vector<ExtClass> varName;
但是,我想做的是:
由于 varName 现在是 ExtClass 类型,我想在另一个 class 中调用它的构造函数。澄清一下,我认为代码将对此进行最好的解释:
class ExtClass {
public:
int ext;
int pet;
ExtClass();
};
ExtClass:ExtClass() {
this->ext = std::rand();
this->pet = std::rand();
}
________________________
class MainClass {
public:
std::vector<ExtClass> attribute;
MainClass(int);
}
MainClass(int size) {
this->attribute.reserve(size) // reserving enough places in vector
for (int i = 0; i < size; ++i)
this->attribute[i] = new ExtClass(); // problem
}
我已经使用了所有 public 成员以避免不必要的代码。
我想因为 std::vector 属性是一个 ExtClass 元素的向量,并且因为 none 已经被定义,所以我可以将向量的每个元素分配为:
new ExtClass()
这将创建,例如:
attribute[0].ext = 5125;
attribute[0].pet = 151;
这绝对不是这种情况,编译器在这一行上争论:
note: candidate: constexpr ExtClass& ExtClass::operator=(const ExtClass&)
class ExtClass {
^~~~~~
note: no known conversion for argument 1 from ‘ExtClass*’ to ‘const ExtClass&’
note: candidate: constexpr ExtClass& ExtClass::operator=(ExtClass&&)
note: no known conversion for argument 1 from ‘ExtClass*’ to ‘ExtClass&&’
我不是 C++ 专家,但对它比较陌生,我正在练习。你能告诉我我的错误是什么吗?我做错了什么假设?
谢谢!
编写的代码可以通过以下方式修复:
MainClass(int size)
: attribute( size )
{
}
就是这样,它将使用 ExtClass
的 size
个默认构造对象初始化 attribute
。
注意这段代码:
this->attribute.reserve(size) // reserving enough places in vector
for (int i = 0; i < size; ++i)
this->attribute[i] = new ExtClass(); // problem
即使我们将其修复为可编译:
this->attribute.reserve(size) // reserving enough places in vector
for (int i = 0; i < size; ++i)
this->attribute[i] = ExtClass(); // problem
当您尝试访问空向量的元素时会导致 UB - 调用 reserve 不会改变向量持有的对象数量,只会改变未来使用的容量。
如上评论所示,您可以替换:
for (int i = 0; i < size; ++i)
this->attribute[i] = new ExtClass();
与:
for (int i = 0; i < size; ++i)
this->attribute.emplace_back ();
然后您的矢量将为您管理 ExtClass
对象的生命周期。
我一直在谷歌搜索和 Whosebuging 这个问题,但找不到任何答案。
我想做的是创建一个带有自定义 class 的向量,我对此没有问题。我明白我需要做的:
std::vector<ExtClass> varName;
但是,我想做的是:
由于 varName 现在是 ExtClass 类型,我想在另一个 class 中调用它的构造函数。澄清一下,我认为代码将对此进行最好的解释:
class ExtClass {
public:
int ext;
int pet;
ExtClass();
};
ExtClass:ExtClass() {
this->ext = std::rand();
this->pet = std::rand();
}
________________________
class MainClass {
public:
std::vector<ExtClass> attribute;
MainClass(int);
}
MainClass(int size) {
this->attribute.reserve(size) // reserving enough places in vector
for (int i = 0; i < size; ++i)
this->attribute[i] = new ExtClass(); // problem
}
我已经使用了所有 public 成员以避免不必要的代码。
我想因为 std::vector 属性是一个 ExtClass 元素的向量,并且因为 none 已经被定义,所以我可以将向量的每个元素分配为:
new ExtClass()
这将创建,例如:
attribute[0].ext = 5125;
attribute[0].pet = 151;
这绝对不是这种情况,编译器在这一行上争论:
note: candidate: constexpr ExtClass& ExtClass::operator=(const ExtClass&)
class ExtClass {
^~~~~~
note: no known conversion for argument 1 from ‘ExtClass*’ to ‘const ExtClass&’
note: candidate: constexpr ExtClass& ExtClass::operator=(ExtClass&&)
note: no known conversion for argument 1 from ‘ExtClass*’ to ‘ExtClass&&’
我不是 C++ 专家,但对它比较陌生,我正在练习。你能告诉我我的错误是什么吗?我做错了什么假设?
谢谢!
编写的代码可以通过以下方式修复:
MainClass(int size)
: attribute( size )
{
}
就是这样,它将使用 ExtClass
的 size
个默认构造对象初始化 attribute
。
注意这段代码:
this->attribute.reserve(size) // reserving enough places in vector
for (int i = 0; i < size; ++i)
this->attribute[i] = new ExtClass(); // problem
即使我们将其修复为可编译:
this->attribute.reserve(size) // reserving enough places in vector
for (int i = 0; i < size; ++i)
this->attribute[i] = ExtClass(); // problem
当您尝试访问空向量的元素时会导致 UB - 调用 reserve 不会改变向量持有的对象数量,只会改变未来使用的容量。
如上评论所示,您可以替换:
for (int i = 0; i < size; ++i)
this->attribute[i] = new ExtClass();
与:
for (int i = 0; i < size; ++i)
this->attribute.emplace_back ();
然后您的矢量将为您管理 ExtClass
对象的生命周期。