2D矢量调整大小需要对象的默认构造函数



我有一个简单的球类。它的初始化需要一个颜色名。

Ball::Ball(ColorName color_name) : m_color_name{color_name} {
}

我尝试创建一个2d矢量板来包含一些球。宽度和高度由外部给出。

class Board {
private:
int m_width;
int m_height;
std::vector<std::vector<Ball>> m_grids;
public:
Board(int width, int height);
~Board();
};
Board::Board(int width, int height) : m_width{width}, m_height{height} {
m_grids.resize(height);
for (int row_num = 0; row_num < height; row_num ++) {
m_grids[row_num].resize(width);
}
}

那么编译器就会抱怨ball类需要默认构造函数来调整大小。

然后我试着把它改成指针

class Board {
private:
int m_width;
int m_height;
std::vector<std::vector<Ball> *> *m_grids;
public:
Board(int width, int height);
~Board();
};
Board::Board(int width, int height) : m_width{width}, m_height{height} {
m_grids->resize(height);
for (int row_num = 0; row_num < height; row_num ++) {
m_grids->at(row_num)->resize(width);
}
}

Board::Board(int width, int height) : m_width{width}, m_height{height} {
m_grids->resize(height, new std::vector<Ball>[width]);
for (int row_num = 0; row_num < height; row_num ++) {
m_grids->at(row_num)->resize(width);
}
}

他们仍然抱怨同样的事情。

到目前为止,我只能创建默认构造函数来解决这个问题。
Ball::Ball() {
m_color_name = ColorName::Default;
}

但我真的不喜欢它,因为球不应该是&;default_color&;。应该是"黄色"、"粉红色";或者我在别处定义的颜色

是否有一种方法可以避免创建构造函数?

好吧,如果你不知道一个新的空板上的球应该是什么颜色,c++不能帮你。您没有为该类型提供默认构造函数,因此c++无法知道使用哪个默认值。这里有几个选项。

。使用std::optional<ColorName>板。在这种情况下,您将有一个显式的"default"状态是std::nullopt。但是,如果需要的话,您需要小心,并始终确保颜色被放置。

2。不要预先创建板。只有当你知道应该用什么颜色的时候才创建它。例如,它是可以做m_grids[row_num].push_back(ColorName::Whatever);,你不需要一个默认的构造函数。

至于指针(无论是原始的还是智能的)——忘记它吧。在这个任务中你不需要指针。

与其将向量转换为指针(这没有任何意义),不如将元素本身转换为指针。由于指针可以是空ptr类型,因此向量可以调整大小,如下所示:

std::vector<std::vector<Ball *>> m_grids_bad;
// Or even better:
std::vector<std::vector<std::unique_ptr<Ball>>> m_grids;
// You can then assign things like this (for example):
m_grids[4][5] = std::make_unique<Ball>(ColorName::RED, 5);

我强烈建议您尽可能使用std::unique_ptrstd::shared_ptr,因为没有人反对它。它可以帮助你在抛出异常时释放内存,或者允许你共享一些内存地址的所有权,等等。去做吧。

调整向量的大小现在可以像你想的那样工作了,因为std::unique_ptr有一个默认构造函数,它只是初始化了指向nullptr的内部指针。

PS:也许我应该详细说明为什么在堆上存储向量没有意义。向量已经可以将其内容存储在堆上,并在需要时动态重新分配内存。

另一件事:如果元素类型是不可移动的,指向指针的向量也非常有用。这在多线程情况下很有用,在多线程情况下,线程有时会用指向某个对象的指针初始化,并依赖该对象精确地留在内存中的位置。

最新更新