【问题标题】:C++: Passing a (pointer to an?) array of objects by referenceC ++:通过引用传递(指向?)对象数组
【发布时间】:2014-02-14 21:34:29
【问题描述】:

我是 C++ 新手,在使用指针传递和引用创建对象数组时遇到了很大的麻烦。这不是实际的代码;这是代码本质上的一个示例。

#include <iostream>

class MyClass
{
    public:
        MyClass();
        static int doStuff(MyClass *&classArray);
        void print_number();

    private:
        int number;
};

MyClass::MyClass()
{

}

int MyClass::doStuff(MyClass *&classArray)
{
    int i = 0;
    for (i = 0; i < 10; i++) {
        *classArray[i].number = i;
    }
    return i;
}

void MyClass::print_number()
{
    std::cout << number << "\n";
}

int main(void)
{
    MyClass *test = nullptr;
    int p = MyClass::doStuff(test);
    std::cout << p << '\n';
    for (int i = 0; i < 10; i++) {
        test[i].print_number();
    }
    return 0;
}

编译时,这会产生分段错误。

【问题讨论】:

  • 您永远不会分配内存来保存MyClass 的实例。你应该写(主要)MyClass test[10];而不是MyClass *test = NULL;
  • @leemes 我的错误:在实际代码中它是MyClass *class = nullptr。我会解决的。
  • 这或多或少是一样的。两者都不分配任何内存。我说MyClass test[10];

标签: c++ arrays parameter-passing


【解决方案1】:

这就是你的做法(不要忘记在程序或析构函数的末尾使用delete[] 删除classArray:


new 运算符必须有默认构造函数,如果要使用非默认构造函数,创建复制构造函数更容易,然后创建一个临时对象并复制。

#include <iostream>

class MyClass
{
public:
    MyClass();
    MyClass(int x, int y);
    MyClass(MyClass &OldClass);
    static int doStuff(MyClass *&classArray, int Size, int x, int y);
    void print_number();

private:
    int number, x, y;
};

MyClass::MyClass()
{
    number = 0;
    x = 0;
    y = 0;
}

MyClass::MyClass(int x, int y)
{
    number = 0;
    this->x = x;
    this->y = y;
}

MyClass::MyClass(MyClass &OldClass)
{
    this->number = OldClass.number;
    this->x = OldClass.x;
    this->y = OldClass.y;
}

int MyClass::doStuff(MyClass *&classArray, int Size, int x, int y)
{
    if (Size > 0)
    {
        classArray = new MyClass[Size];
        for (int i = 0; i < Size; i++)
        {
            classArray[i] = MyClass(x, y);
            classArray[i].number = i;
        }

        return Size;
    }
    else
        return 0;
}

void MyClass::print_number()
{
    std::cout << number << " " << x << " " << y << "\n";
}

int main(void)
{
    MyClass *test = nullptr;
    int p = MyClass::doStuff(test, 10, 5, 6);
    std::cout << p << '\n';
    for (int i = 0; i < p; i++) {
        test[i].print_number();
    }
    delete[] test;
    std::cin.get();
    return 0;
}

【讨论】:

  • 实际的类有一个构造函数,我设置它接受两个参数。我将如何考虑这一点——比如MyClass insertedClass(arg1, arg2); classArray[i] = inserted class
  • 我会试着在几秒钟内给你一个例子。
【解决方案2】:

它不起作用,因为您需要分配数组,因为该函数正在尝试访问尚未初始化以容纳该数量元素的数组的元素。你可以这样做

MyClass *test = new MyClass[array_size];

或者

MyClass test[array_size];

或者通过使用可调整大小的容器,例如 std::vector,并相应地更改函数参数

【讨论】:

    【解决方案3】:
        *classArray[i].number = i;
    

    您使用空指针调用 doStuff,因此 classArray 为空且不是数组。取消引用空指针会导致未定义的行为,并且在大多数实现中,您通常会遇到崩溃。


    您还取消了非指针的引用,因此该代码甚至无法编译。我得到的错误是:

    main.cpp:23:9: error: indirection requires pointer operand ('int' invalid)
            *classArray[i].number = i;
            ^~~~~~~~~~~~~~~~~~~~~
    

    这大概是因为,正如您所说,您显示的代码不是您的真实代码,classArray[i].number 对应于您真实代码中的指针。但我想我还是要指出这一点,以防万一。

    【讨论】:

      【解决方案4】:

      鉴于您的代码上下文,这是您的代码的一个工作示例:

      #include <iostream>
      
      class MyClass
      {
          public:
              MyClass() {}
      
              static int doStuff(MyClass*& classArray, size_t sz)
              {
                  int i = 0;
                  for (; i < sz; i++) {
                      classArray[i].number = i;
                  }
                  // not sure what you want here, but this will return sz+1 if sz>0
                  return i;
              }
      
              void print_number()
              {
                  std::cout << this->number << std::endl;
              }
      
          private:
              int number;
      };
      
      int main(void)
      {
          MyClass* test = new MyClass[10];
          int p = MyClass::doStuff(test, 10);
          std::cout << p << '\n';
          for (int i = 0; i < 10; i++) {
              test[i].print_number();
          }
          delete[] test;
          return 0;
      }
      

      尽管正如其他人指出的那样,您使用的是 C++,虽然这是一个很好的练习,可以帮助您了解如何传递指针和数组,但您可能会发现 STLC++stdlib 在'更容易理解上下文'。

      这是你的一些 C++ STL 代码:

      #include <iostream>
      #include <vector>
      
      class MyClass
      {
          public:
              MyClass() {}
              MyClass(int i) : number(i) {}
      
              static int doStuff(std::vector<MyClass>& classArray, size_t sz)
              {
                  int i = 0;
                  for (; i < sz; i++) {
                      classArray.push_back(MyClass(i));
                  }
                  // not sure what you want here, but this will return sz+1 if sz>0
                  return i;
              }
      
              void print_number()
              {
                  std::cout << this->number << std::endl;
              }
      
          private:
              int number;
      };
      
      int main(void)
      {
          std::vector<MyClass> test;
          int p = MyClass::doStuff(test, 10);
          std::cout << test.size() << '\n';
          // can use iterators here if you want
          std::vector<MyClass>::iterator itr = test.begin();
          for (; itr != test.end(); itr++) {
              itr->print_number();
          }
          return 0;
      }
      

      希望能有所帮助。

      【讨论】:

        猜你喜欢
        • 2016-05-27
        • 2020-07-12
        • 1970-01-01
        • 1970-01-01
        • 2021-06-04
        • 1970-01-01
        • 2011-07-06
        • 2014-07-26
        • 1970-01-01
        相关资源
        最近更新 更多