gpt4 book ai didi

c++ - 数组大小作为构造函数参数

转载 作者:搜寻专家 更新时间:2023-10-31 01:04:34 24 4
gpt4 key购买 nike

我正在创建一个 C++ 类,它包装一个浮点二维数组并提供一些额外的功能。我想将数组的形状作为参数传递给构造函数,请参见下面的代码(类 Block 部分)。以注释“//here”结尾的行会在编译期间导致错误,因为 _nx 和 _ny 在那时是未知的。围绕这个有两种解决方案(我认为):一种是使用指针(参见下面代码中的解决方案 1)并动态分配数组;另一个是使用模板(参见下面代码中的解决方案 2),但我有几个不使用它们的原因:

  1. 只要没有指针,我就不想使用指针选项;换句话说,我不想使用 new 和 delete。这这样做的原因是个人偏爱更纯的 C++。
  2. 我不想使用模板,因为可以有许多不同的 block 形状 - 我不希望编译器为它们中的每一个创建许多类,这是一种矫枉过正,会增加可执行文件的大小。

另外,我不想使用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。一周前我遇到了同样的决策问题并问过here .

如果您使用 reserve(),它不会使您的 vector 多次重新分配自身(如果有的话),那么 vectors 不会将影响您的项目的性能。换句话说,vector 不太可能成为您的瓶颈。

请注意,在 C++ 中,vectors 被广泛使用,因此在 release 模式 中,优化他们真的很有效率。

或者等待std::dynarray待介绍! (不幸的是,不是在 C++14 中,而是在 array TSC++17 中)。 Source , 归功于 manlio。

永远不要忘记:过早的优化是万恶之源。 - Knuth。

不相信我?你不应该!亲自试验并找出答案!

这是我的实验,当我遇到与您完全相同的问题时,我可以说服自己。

实验代码:

#include <iostream>
#include <vector>
#include <ctime>
#include <ratio>
#include <chrono>

using namespace std;

int main() {
const int N = 100000;


cout << "Creating, filling and accessing an array of " << N << " elements.\n";

using namespace std::chrono;

high_resolution_clock::time_point t1 = high_resolution_clock::now();

int array[N];

for(int i = 0; i < N; ++i)
array[i] = i;

for(int i = 0; i < N; ++i)
array[i] += 5;

high_resolution_clock::time_point t2 = high_resolution_clock::now();

duration<double> time_span = duration_cast<duration<double>>(t2 - t1);

std::cout << "It took me " << time_span.count() << " seconds.";
std::cout << std::endl;


cout << "Creating, filling and accessing an vector of " << N << " elements.\n";

t1 = high_resolution_clock::now();

vector<int> v;
v.reserve(N);

for(int i = 0; i < N; ++i)
v.emplace_back(i);

for(int i = 0; i < N; ++i)
v[i] += 5;

t2 = high_resolution_clock::now();

time_span = duration_cast<duration<double>>(t2 - t1);

std::cout << "It took me " << time_span.count() << " seconds.";
std::cout << std::endl;

return 0;
}

结果(注意 -o2 编译器标志):

samaras@samaras-A15:~$ g++ -std=gnu++0x -o2 px.cpp
samaras@samaras-A15:~$ ./a.out
Creating, filling and accessing an array of 100000 elements.
It took me 0.002978 seconds.
Creating, filling and accessing an vector of 100000 elements.
It took me 0.002264 seconds.

所以,只是一个std::vector。 :) 我很确定您知道如何为此更改代码,您不需要我告诉您(是这样,当然让我知道 :))。

您可以尝试其他时间方法,在我的 pseudo-site 中找到.

关于c++ - 数组大小作为构造函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23703837/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com