【发布时间】:2014-05-16 20:13:44
【问题描述】:
我正在创建一个包含浮点二维数组并提供一些附加功能的 C++ 类。我想将数组的形状作为参数传递给构造函数,请参见下面的代码(类 Block 部分)。以注释“// here”结尾的行会在编译期间导致错误,因为当时不知道 _nx 和 _ny。 对此有两种解决方案(我认为):一种是使用指针(参见下面代码中的解决方案1)并动态分配数组;另一种是使用模板(见下面代码中的解决方案2),但我有几个理由不使用它们:
- 只要有无指针,我就不想使用指针 选项;换句话说,我不想使用 new 和 delete。这 原因是个人偏好更纯粹的 c++。
- 我不想要 使用模板,因为可以有许多不同的块形状 - 我 不希望编译器为每个类创建许多类, 这是一种矫枉过正的做法,会增加可执行文件的大小。
另外,我不想使用stl vector,因为数组大小在创建后是固定的;我也在做数值计算,所以“原始”数组更适合我。
我在 SO 中搜索过,有五六个问题问类似的问题,但没有结论哪个更好,而且没有一个是从数字立场出发的,所以 vector 或 new/detele 对他们来说是很好的答案- 但不适合我。我发布这个问题的另一个原因是我想知道我在使用 c++ 功能时是否过于严格。由于我将广泛使用 c++,因此了解 c++ 的局限性并停止过多地询问/搜索某些不存在的功能非常重要。
#include <iostream>
#include <memory>
using namespace std;
class Block
{
public:
Block(int nx, int ny):_nx(nx),_ny(ny){}
void Report(void)
{
cout << "Block With Size ["<<_nx<<","<<_ny<<"]\n";
}
private:
const int _nx, _ny;
double _data[_nx][_ny]; // here
};
/// Solution 1, using auto_ptr
class BlockAuto
{
public:
BlockAuto(int nx, int ny):_nx(nx),_ny(ny),_data(new double[_nx*_ny]){}
void Report(void)
{
cout << "BlockAuto With Size ["<<_nx<<","<<_ny<<"]\n";
}
private:
const int _nx;
const int _ny;
const auto_ptr<double> _data;
};
/// Solution 2, using template
template<unsigned int nx, unsigned int ny>
class BlockTpl
{
public:
BlockTpl():_nx(nx),_ny(ny){}
void Report(void)
{
cout << "BlockTpl With Size ["<<_nx<<","<<_ny<<"]\n";
}
private:
const int _nx;
const int _ny;
double _data[nx][ny]; // uncomfortable here, can't use _nx, _ny
};
int main(int argc, const char *argv[])
{
Block b(3,3);
b.Report();
BlockAuto ba(3,3);
ba.Report();
BlockTpl<3,4> bt;
bt.Report();
return 0;
}
【问题讨论】:
-
如果你不调整它们的大小,
std::vector不会比原始数组慢。 -
我不明白为什么不使用指针是“更纯粹的”。但是我认为如果你真的可以利用不使用
std::vector的优势,那么指针解决方案比向量更可取(考虑到你使用优化标志,这在现代编译器中并不比战争慢)
标签: c++ arrays constructor