【问题标题】:Return array in C++在 C++ 中返回数组
【发布时间】:2011-12-17 16:36:38
【问题描述】:

我是一个完全的 C++ 菜鸟,我在从我的方法返回一个数组时遇到了一些麻烦。我有一个带有以下方法声明的头文件:

virtual double[]
echoDoubleArray(double[] doubleArray, int arraySize) throw (RemoteException);

这给了我以下错误:

../common/EchoService.h: At global scope:
../common/EchoService.h:25: error: expected unqualified-id before ‘[’ token

返回数组的正确方法是什么?

【问题讨论】:

  • 请记住,异常规范已被正式弃用。
  • 不要使用异常规范,它们不会像大多数人想的那样做。它们在 C++11 中已被弃用。
  • 返回双精度数组的函数的正确语法是double foo()[5]。但是,C 和 C++ 都不允许函数返回数组。

标签: c++ arrays return


【解决方案1】:

C++ 不能很好地处理非本地数组,您更有可能应该使用像 std::array<double,10>std::vector<double> 这样的实际容器。我认为不可能从函数返回数组。

【讨论】:

    【解决方案2】:

    你最好使用 std::vector 或者如果你真的想返回一个普通数组,返回一个指针(指向这样一个数组)动态分配,例如

    double* arr = new double[arrSize];
    // fill arr appropriately
    return arr;
    

    但我建议改为返回 std::vector<double>

    【讨论】:

      【解决方案3】:

      有一种传递数组的技术不会衰减到指针。您可以使用以下语法通过引用传递数组。所需的“额外”括号是语法上的缺陷,这可能是为什么这种用法不常见的原因。考虑到优势,人们很快就会习惯它。

      void sub(double (&foo)[4])
      {
          cout << sizeof(foo) << endl;
      }
      

      打印 32,而不是 sizeof(double*),因为 foo 的类型确实对 4 个双精度数组的引用。使用模板,您可以泛化以适用于任何大小的数组:

      template <int N> sub(double (&foo)[N])
       {
          cout << sizeof(foo) << endl;
       }
      
       double bar[5];
       double zot[3];
       sub(bar); // ==> 40
       sub(zot); // ==> 24
      

      您可以再次泛化以处理任意大小的数组:

      template <class T, int N>void sub(T(&foo)[N])
          {
              cout << sizeof(foo) << endl;
          }
      
      double bar[5];
      char zot[3];
      sub(bar); // ==> 40
      sub(zot); // ==> 3
      

      现在,无论您传递给它的数组的类型或大小如何,您都可以捕捉到“sub”的抽象概念。

      【讨论】:

        【解决方案4】:

        数组的 C++ 语法是:std::vector&lt;double&gt; 而不是 double[]。它还要求您将#include &lt;vector&gt; 放在源文件顶部附近。除此之外,它们的工作方式与 C 数组非常相似。

        【讨论】:

        • 这个答案非常具有误导性。
        • 为了解释如何它会产生误导,std::vector 是数组的替代品,而不是它们的替代品。 C++ 仍然有 C 风格的数组,它们令人困惑的依赖于指针的荣耀。
        • 我投了反对票,因为数组的 C++ 语法是 not std::vector.
        【解决方案5】:

        为了更直接地回答您的问题,如果您声明一个双精度数组,如下所示:

        double doubleArray[] = {1.0, 2.0, 3.0};
        

        你可以像这样声明方法:

        virtual double *
        echoDoubleArray(double* doubleArray, int arraySize) throw (RemoteException);
        

        数组作为指针传递。如果您想使用 C++ 的真正力量,请遵循其他答案中提供的建议。

        【讨论】:

          【解决方案6】:

          抱歉,似乎每个人都在告诉您使用现代 STL 类型编程而不是回答您的问题。他们正确的。但是你仍然应该了解事情是如何运作的。返回数组的问题是在您的函数中创建的数组将在堆栈上。当您离开您的功能时,它们将不再存在。您可以做的是返回指向堆上数组的指针。对堆栈和堆进行更多研究以了解。但下面是一个简单的 C++ 函数,返回一个分配在堆上的数组。

          #include <iostream>
          
          double * MakeArray()
          {
             double *mydouble = new double[5]; 
             mydouble[1]=1.1;
             mydouble[1]=2.2;
            return mydouble;
          }
          
          int main()
          {
          
            double *d=MakeArray();
            std::cout<<d[1]<<d[2];
            delete[] d; 
          }
          

          编辑:

          再想一想,不使用 STL 的另一种方法是返回一个包含数组的结构。大多数编译器将按值返回一个结构(假设您不进行嵌入式编程)。

          可能是最好的简单方法:将您的数组传递给函数。这就像传递一个引用,因为你实际上只是传递一个指针。

          #include <iostream>
          
          void MakeArray(double d[5])
          {
            d[0] = 0.0; d[1] = 1.1;
            d[2] = 2.2; d[3] = 3.3; d[4] =4.4;
          }
          
          int main()
          {
            double dub[5];
            MakeArray(dub);
            std::cout<<dub[1]<<dub[2];
          }
          

          在了解一切如何运作之后。去使用 STL。

          【讨论】:

          • 问题不在于数组在堆栈上。返回的所有其他内容也是如此,包括指向函数中动态数组的指针。 Mooing Duck 更准确地说明了这个问题“C++ 不能很好地处理非本地数组”,因为几乎所有其他构造都可以按值返回,并制作一个副本。但是数组不能。
          • 请注意,参数声明中的5 被忽略。以下都是等效的:void MakeArray(double d[5])void MakeArray(double d[])void MakeArray(double *d)
          • @benjamin Lindely : 播放不好的原因是什么?
          • @JoeMcGrath:就像我说的那样,它们不能按值返回,即使几乎所有其他构造都可以(只要它具有公共复制 ctor)。或者你在问我为什么它们不能按值返回?
          • @JoeMcGrath:我不知道,我不太感兴趣。
          猜你喜欢
          • 2017-02-01
          • 2015-07-31
          • 2021-12-24
          • 2014-12-22
          • 2011-01-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多