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

标签 c++ arrays constructor

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

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

另外,我不想使用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 多次重新分配自身(如果有的话),那么 vector 就不会将影响您的项目的绩效。换句话说,vector 不太可能成为您的瓶颈。

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

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

永远不要忘记:过早的优化是邪恶之源。 - 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/

相关文章:

c++ - 在没有迭代器 C++ 的 std::set 中搜索

c++ - program.exe : 0xC0000005: Access violation reading location 0xCCCCCCD0 中 0x010F2F1C 处未处理的异常

c++ - 返回私有(private)数组

java - 与 @Builder 结合使用时,我无法让 @RequiredArgsConstructor 工作

Java Lombok : Omitting one field in @AllArgsConstructor?

c++ - 在 Ada95/构造函数和受控类型中使用 C++ 类

c++ - 静态分配boost Graph

c++ - 将 STL 字符串数组转换为 const char* 数组的最有效方法是什么?

javascript - 在二维数组中分配值时遇到问题

arrays - PowerShell foreach 如何跳过最后一个元素