在 C++ 中单独定义和初始化一个列表
Defining and initializing a List separately in C++
我正在用 C++ 为 CFD 软件 OpenFOAM 编写一个插件。我的代码将为分析的每个时间步从模型中的每个单元格(> 100k 单元格)读取信息。我有一个名为 C 的双精度列表列表,它在第一个时间步中用零初始化,并在接下来的时间步中发生变化,但大小保持不变。
我的问题是第一个时间步骤中列表的初始化花费了太多时间。在接下来的时间步骤中,我可以轻松地遍历列表中的所有元素并对这些值执行一些计算并再次存储它们。然而,在第一个时间步骤中,我有一个大小为 0 的空列表,这意味着我也附加了零来初始化它。我确实知道列表的最终大小,所以我可以轻松地写
Foam::List<Foam::List<double>> C (size,0.0);
在第一个时间步,我的问题就解决了(这是 OpenFOAM 特定列表 class https://www.openfoam.com/documentation/guides/latest/api/classFoam_1_1List.html)
但是,如果我想一次定义我的列表列表,然后在所有时间步骤中使用它,我需要在头文件中定义它。在头文件中我不知道大小,这意味着我将它定义为
Foam::List<Foam::List<double>> C;
在头文件中,然后在C文件中用零填充。这是我的问题 - 如何在 C 文件中用零初始化一个已经定义的列表列表?
如果这是 C#,我可以将它分成两行,如
List<List<double>> C;
C = new List<List<double>>(size);
并在头文件中写入第一行,在C文件中写入第二行(据我所知)。我怎样才能在 C++ 中做类似的事情?
非常感谢您对此的帮助。
谢谢,
大卫
假设 Foam::List<Foam::List<double>> C;
在您的 .h
文件中定义,并且 size
是一个包含列表的两种大小的双元素数组,您应该能够:
C=Foam::List<Foam::list<double>>(size[0],Foam::List<double>(size[1],0));
另一件事,我想你应该知道,关键字 new
不应该在 c++ 中用于这样的事情。关键字 new
在堆上而不是堆栈上分配内存。每当您使用 new
时,您以后还必须使用 delete
以避免内存泄漏。通常这是通过在 类 CTOR 中使用 new
和在 类 DTOR 中使用 delete
来完成的。正如 @MaxLanghof 在现代 C++ 中正确指出的那样,您应该始终更喜欢使用 std::shared_pointer
、std::unique_pointer
和 std::weak_pointer
等智能指针,而不是 new
和 delete
由于要初始化的变量是class的成员,正常的初始化方法是使用构造函数的成员初始化列表:
头文件:
class MyPlugIn
{
public:
MyPlugIn(int listSize); // constructor
protected:
Foam::List<Foam::List<double>> C;
};
源文件:
MyPlugIn(int listSize) : C(listSize)
{
}
这当然需要在创建 MyPlugIn
时知道必要的大小。如果不是这种情况,使用 Max 答案中所示的 copy/move 赋值运算符也是一种解决方案。
如果它是一个普通列表,您可以使用其中任何一个,具体取决于您是否需要重新调整尺寸或者它是否已经具有正确的大小:
mylist.resize(size, Zero);
mylist = Zero;
如果您有列表的列表,我们会假设它们的大小正确并且将它们归零:
for (auto &lst : mylistlist)
{
lst = Zero;
}
我会使用 Zero
常量而不是 0.0
或其他任何东西 - 它使含义清晰并且很好地适用于 vector/tensor 和其他矢量 - space 数量如果您将来需要它。
我正在用 C++ 为 CFD 软件 OpenFOAM 编写一个插件。我的代码将为分析的每个时间步从模型中的每个单元格(> 100k 单元格)读取信息。我有一个名为 C 的双精度列表列表,它在第一个时间步中用零初始化,并在接下来的时间步中发生变化,但大小保持不变。
我的问题是第一个时间步骤中列表的初始化花费了太多时间。在接下来的时间步骤中,我可以轻松地遍历列表中的所有元素并对这些值执行一些计算并再次存储它们。然而,在第一个时间步骤中,我有一个大小为 0 的空列表,这意味着我也附加了零来初始化它。我确实知道列表的最终大小,所以我可以轻松地写
Foam::List<Foam::List<double>> C (size,0.0);
在第一个时间步,我的问题就解决了(这是 OpenFOAM 特定列表 class https://www.openfoam.com/documentation/guides/latest/api/classFoam_1_1List.html)
但是,如果我想一次定义我的列表列表,然后在所有时间步骤中使用它,我需要在头文件中定义它。在头文件中我不知道大小,这意味着我将它定义为
Foam::List<Foam::List<double>> C;
在头文件中,然后在C文件中用零填充。这是我的问题 - 如何在 C 文件中用零初始化一个已经定义的列表列表?
如果这是 C#,我可以将它分成两行,如
List<List<double>> C;
C = new List<List<double>>(size);
并在头文件中写入第一行,在C文件中写入第二行(据我所知)。我怎样才能在 C++ 中做类似的事情?
非常感谢您对此的帮助。
谢谢, 大卫
假设 Foam::List<Foam::List<double>> C;
在您的 .h
文件中定义,并且 size
是一个包含列表的两种大小的双元素数组,您应该能够:
C=Foam::List<Foam::list<double>>(size[0],Foam::List<double>(size[1],0));
另一件事,我想你应该知道,关键字 new
不应该在 c++ 中用于这样的事情。关键字 new
在堆上而不是堆栈上分配内存。每当您使用 new
时,您以后还必须使用 delete
以避免内存泄漏。通常这是通过在 类 CTOR 中使用 new
和在 类 DTOR 中使用 delete
来完成的。正如 @MaxLanghof 在现代 C++ 中正确指出的那样,您应该始终更喜欢使用 std::shared_pointer
、std::unique_pointer
和 std::weak_pointer
等智能指针,而不是 new
和 delete
由于要初始化的变量是class的成员,正常的初始化方法是使用构造函数的成员初始化列表:
头文件:
class MyPlugIn
{
public:
MyPlugIn(int listSize); // constructor
protected:
Foam::List<Foam::List<double>> C;
};
源文件:
MyPlugIn(int listSize) : C(listSize)
{
}
这当然需要在创建 MyPlugIn
时知道必要的大小。如果不是这种情况,使用 Max 答案中所示的 copy/move 赋值运算符也是一种解决方案。
如果它是一个普通列表,您可以使用其中任何一个,具体取决于您是否需要重新调整尺寸或者它是否已经具有正确的大小:
mylist.resize(size, Zero);
mylist = Zero;
如果您有列表的列表,我们会假设它们的大小正确并且将它们归零:
for (auto &lst : mylistlist)
{
lst = Zero;
}
我会使用 Zero
常量而不是 0.0
或其他任何东西 - 它使含义清晰并且很好地适用于 vector/tensor 和其他矢量 - space 数量如果您将来需要它。