在 CPP 的构造函数中初始化二维数组 class
Initialize 2D array in constructor of CPP class
我想知道在 cpp class 中初始化二维数组的最佳方法是什么。在调用构造函数之前我不知道它的大小,即
头文件包含:
private:
int size;
bool* visited;
int edges;
int** matrix;
默认构造函数(现在):
Digraph::Digraph(int n) {
int rows = (n * (n-1)/2);
int columns = 2;
matrix = new int[rows][2];
visited[size] = { 0 };
size = n;
edges = 0;
}
我要的是N行2列的二维数组
当我尝试编译时,目前 returns error: cannot convert 'int (*)[2]' to 'int**' in assignment
。
注意:我不会使用矢量,所以请不要推荐它们。
matrix = new int[rows][2];
是无效语法。分配一个二维稀疏数组需要多次new[]
调用,例如:
private:
int size;
bool* visited;
int edges;
int** matrix;
int rows;
int columns;
...
Digraph::Digraph(int n) {
size = n;
edges = 0;
rows = (n * (n-1)/2);
columns = 2;
matrix = new int*[rows];
for(int x = 0; x < rows; ++x) {
matrix[x] = new int[columns];
for(int y = 0; y < columns; ++y)
matrix[x][y] = 0;
}
visited = new bool[size];
for(int x = 0; x < size; ++x)
visited[x] = false;
}
Digraph::~Digraph() {
for(int x = 0; x < rows; ++x) {
delete[] matrix[x];
}
delete[] matrix;
delete[] visited;
}
或者,考虑将 matrix
分配为一维数组,然后在访问其值时使用二维索引,例如:
private:
int size;
bool* visited;
int edges;
int* matrix; // <-- 1 *, not 2 **
int rows;
int columns;
int& matrix_value(int row, int col) { return matrix[(row * rows) + col]; }
...
Digraph::Digraph(int n) {
size = n;
edges = 0;
rows = (n * (n-1)/2);
columns = 2;
n = rows * columns;
matrix = new int[n];
for(int x = 0; x < n; ++x)
matrix[n] = 0;
visited = new bool[size];
for(int x = 0; x < size; ++x)
visited[x] = false;
}
Digraph::~Digraph() {
delete[] matrix;
delete[] visited;
}
无论哪种方式,您还需要实现(或禁用)复制构造函数和复制赋值运算符,最好是移动构造函数和移动赋值运算符,根据 Rule of 3/5/0,例如:
Digraph::Digraph(const Digraph &src) {
size = src.size;
edges = src.edges;
rows = src.rows;
columns = src.columns;
matrix = new int*[rows];
for(int x = 0; x < rows; ++x) {
matrix[x] = new int[columns];
for (int y = 0; y < columns; ++y)
matrix[x][y] = src.matrix[x][y];
}
/* or:
n = rows * columns;
matrix = new int[n];
for(int x = 0; x < n; ++x)
matrix[n] = src.matrix[n];
*/
visited = new bool[size];
for(int x = 0; x < size; ++x)
visited[x] = src.visited[x];
}
Digraph::Digraph(Digraph &&src) {
size = 0;
edges = 0;
rows = 0;
columns = 0;
matrix = nullptr;
visited = nullptr;
src.swap(*this);
}
void Digraph::swap(Digraph &other) {
std::swap(size, other.size);
std::swap(edges, other.edges);
std::swap(rows, other.rows);
std::swap(columns, other.columns);
std::swap(matrix, src.matrix);
std::swap(visited, src.visited);
}
Digraph& Digraph::operator=(Digraph rhs) {
Digraph temp(std::move(rhs));
temp.swap(*this);
return this;
}
也就是说,更好的设计是使用 std::vector
而不是 new[]
,并让它为您处理所有内存管理和 copying/moving,例如:
#include <vector>
private:
int size;
std::vector<bool> visited;
int edges;
std::vector<std::vector<int>> matrix;
// or: std::vector<int> matrix;
int rows;
int columns;
...
Digraph::Digraph(int n) {
size = n;
edges = 0;
rows = (n * (n-1)/2);
columns = 2;
matrix.resize(rows);
for(int x = 0; x < rows; ++x)
matrix[x].resize(columns);
/* or:
matrix.resize(rows * columns);
*/
visited.resize(size);
}
// implicitly-generated copy/move constructors, copy/move assignment operators,
// and destructor will suffice, so no need to implement them manually...
如果您不能使用 std::vector
,请考虑使用适当的语义实现您自己的 vector
class,然后改用它。你真的应该努力尽可能多地遵循 0 规则,通过使用为你实现 3/5 规则的 classes。
我想知道在 cpp class 中初始化二维数组的最佳方法是什么。在调用构造函数之前我不知道它的大小,即
头文件包含:
private:
int size;
bool* visited;
int edges;
int** matrix;
默认构造函数(现在):
Digraph::Digraph(int n) {
int rows = (n * (n-1)/2);
int columns = 2;
matrix = new int[rows][2];
visited[size] = { 0 };
size = n;
edges = 0;
}
我要的是N行2列的二维数组
当我尝试编译时,目前 returns error: cannot convert 'int (*)[2]' to 'int**' in assignment
。
注意:我不会使用矢量,所以请不要推荐它们。
matrix = new int[rows][2];
是无效语法。分配一个二维稀疏数组需要多次new[]
调用,例如:
private:
int size;
bool* visited;
int edges;
int** matrix;
int rows;
int columns;
...
Digraph::Digraph(int n) {
size = n;
edges = 0;
rows = (n * (n-1)/2);
columns = 2;
matrix = new int*[rows];
for(int x = 0; x < rows; ++x) {
matrix[x] = new int[columns];
for(int y = 0; y < columns; ++y)
matrix[x][y] = 0;
}
visited = new bool[size];
for(int x = 0; x < size; ++x)
visited[x] = false;
}
Digraph::~Digraph() {
for(int x = 0; x < rows; ++x) {
delete[] matrix[x];
}
delete[] matrix;
delete[] visited;
}
或者,考虑将 matrix
分配为一维数组,然后在访问其值时使用二维索引,例如:
private:
int size;
bool* visited;
int edges;
int* matrix; // <-- 1 *, not 2 **
int rows;
int columns;
int& matrix_value(int row, int col) { return matrix[(row * rows) + col]; }
...
Digraph::Digraph(int n) {
size = n;
edges = 0;
rows = (n * (n-1)/2);
columns = 2;
n = rows * columns;
matrix = new int[n];
for(int x = 0; x < n; ++x)
matrix[n] = 0;
visited = new bool[size];
for(int x = 0; x < size; ++x)
visited[x] = false;
}
Digraph::~Digraph() {
delete[] matrix;
delete[] visited;
}
无论哪种方式,您还需要实现(或禁用)复制构造函数和复制赋值运算符,最好是移动构造函数和移动赋值运算符,根据 Rule of 3/5/0,例如:
Digraph::Digraph(const Digraph &src) {
size = src.size;
edges = src.edges;
rows = src.rows;
columns = src.columns;
matrix = new int*[rows];
for(int x = 0; x < rows; ++x) {
matrix[x] = new int[columns];
for (int y = 0; y < columns; ++y)
matrix[x][y] = src.matrix[x][y];
}
/* or:
n = rows * columns;
matrix = new int[n];
for(int x = 0; x < n; ++x)
matrix[n] = src.matrix[n];
*/
visited = new bool[size];
for(int x = 0; x < size; ++x)
visited[x] = src.visited[x];
}
Digraph::Digraph(Digraph &&src) {
size = 0;
edges = 0;
rows = 0;
columns = 0;
matrix = nullptr;
visited = nullptr;
src.swap(*this);
}
void Digraph::swap(Digraph &other) {
std::swap(size, other.size);
std::swap(edges, other.edges);
std::swap(rows, other.rows);
std::swap(columns, other.columns);
std::swap(matrix, src.matrix);
std::swap(visited, src.visited);
}
Digraph& Digraph::operator=(Digraph rhs) {
Digraph temp(std::move(rhs));
temp.swap(*this);
return this;
}
也就是说,更好的设计是使用 std::vector
而不是 new[]
,并让它为您处理所有内存管理和 copying/moving,例如:
#include <vector>
private:
int size;
std::vector<bool> visited;
int edges;
std::vector<std::vector<int>> matrix;
// or: std::vector<int> matrix;
int rows;
int columns;
...
Digraph::Digraph(int n) {
size = n;
edges = 0;
rows = (n * (n-1)/2);
columns = 2;
matrix.resize(rows);
for(int x = 0; x < rows; ++x)
matrix[x].resize(columns);
/* or:
matrix.resize(rows * columns);
*/
visited.resize(size);
}
// implicitly-generated copy/move constructors, copy/move assignment operators,
// and destructor will suffice, so no need to implement them manually...
如果您不能使用 std::vector
,请考虑使用适当的语义实现您自己的 vector
class,然后改用它。你真的应该努力尽可能多地遵循 0 规则,通过使用为你实现 3/5 规则的 classes。