【发布时间】:2020-10-23 21:10:43
【问题描述】:
我想实现一个内存高效的 2D 网格类,因为它将用于 Monte Carlo 模拟。然而,在这个阶段,这实际上与二维数组类相同。不用说,我是 C++ 新手。我写了以下代码。
#define MESH2D_H_INCLUDED
class Mesh2D
{
private:
double* mesh;
size_t rows;
size_t columns;
public:
/* constructor */
Mesh2D(size_t Nx, size_t Ny){
rows = Nx;
columns = Ny;
mesh = new double[Nx*Ny] {};
std::cout << "Mesh created." << std::endl;
}
/* destructor */
~Mesh2D()
{
delete[] mesh;
std::cout << "Mesh deleted." << std::endl;
}
/* accessors */
double getrows() const {return rows;}
double getcolumns() const {return columns;}
double& operator()(size_t i, size_t j)
{
if (i > rows || j > columns){
throw std::out_of_range("Index exceeds array bounds.");
}
return mesh[j + i*columns]; // row major access
}
/* copy constructor */
Mesh2D& operator=(const Mesh2D& rhs) // what is the difference between this line and the following? inline operator=(const Mesh2D& rhs)
{
if (rhs.rows != rows || rhs.columns != columns){
throw std::out_of_range("Assignment cannot be performed, mesh dimensions do not agree.");
}
mesh = new double [rows*columns];
// I want to avoid using a for loop
// for (int i=0; i<rows*columns; i++){
// mesh[i] = rhs.mesh[i];
// }
// Use this instead
memcpy(mesh, rhs.mesh, sizeof(rhs)); //however the output is not the expected.
std::cout << "copied!" << std::endl;
}
};
#endif // MESH2D_H_INCLUDED
//MAIN FUNCTION
#include <iostream>
#include "Mesh2D.h"
void PrintMesh2D(Mesh2D &mesh){ //why isn't it going to work if I add const? I mean: void PrintMesh2D(const Mesh2D &mesh)
for (int i=0; i<mesh.getrows(); i++){
for (int j=0; j<mesh.getcolumns(); j++){
std::cout << mesh(i,j) << " ";
}
std::cout << std::endl;
}
}
int main()
{
Mesh2D mesh{3,3};
Mesh2D newmesh{3,3};
for (int i=0; i<mesh.getrows(); i++){
for (int j=0; j<mesh.getcolumns(); j++){
mesh(i,j) = j + i * mesh.getcolumns();
}
}
newmesh = mesh;
PrintMesh2D(newmesh);
}
我的问题是用 cmets 写的,但我也在这里列出:
-
在复制构造函数内部,
Mesh2D& operator=(const Mesh2D& rhs)这一行和inline operator=(const Mesh2D& rhs)这一行有什么区别? -
再次,在复制构造函数中,我想避免使用 for 循环并改用 memcpy。但是,输出不是预期的,我做错了什么?
-
在 main 函数内部:为什么这不会编译?
void PrintMesh2D(const Mesh2D &mesh) -
最后,实现完成了吗?我的意思是,是否缺少任何重要的特性/功能?
欢迎您给我任何建议。由于我是 C++ 新手,我感觉自己在编写错误的错误代码。
编辑:
我写了以下作为复制构造函数。
/* copy constructor */
Mesh2D (const Mesh2D& rhs)
{
rows = rhs.rows;
columns = rhs.columns;
mesh = new double[rows*columns];
memcpy(mesh,rhs.mesh,rows*columns*sizeof(double));
std::cout << "Copied!" << std::endl;
}
看起来不错?
【问题讨论】:
-
在复制构造函数内部, -- 你的
Mesh类没有复制构造函数。它有一个赋值运算符,因此它缺少Mesh可安全复制的必要函数 -- 由于我是 C++ 新手,我觉得我正在编写错误的错误代码。 - - 如果您使用std::vector<double> mesh;而不是mesh *,您可以缓解所有这些问题。 -
您的测试代码不是一个好的测试。这个简单的 2 行程序会导致问题:
int main() { Mesh2D mesh{3,3}; Mesh2D newmesh = mesh; }-- 这表明问题是因为缺少复制构造函数。 -
您应该阅读rule of 3。您的赋值运算符泄漏内存——事实上,您在赋值运算符中的所有代码都应该在复制构造函数中。除此之外,赋值运算符(和复制构造函数)根本不应该检查任何网格条件——它应该复制发送给它的任何内容,无论好坏。否则,您会得到假副本作为合法副本传递,从而导致一些非常难以发现的错误发生。
-
所以我只写了这个:``` /* 复制构造函数 /Mesh2D (const Mesh2D& rhs) { rows = rhs.rows;列 = rhs.columns;网格=新双[行列]; memcpy(mesh,rhs.mesh,rowscolumnssizeof(double)); std::cout
-
您需要将其添加到您的原始帖子中,而不是在评论中。
标签: c++ arrays class multidimensional-array mesh