尝试将对象数组传递给函数时出错

Posted

技术标签:

【中文标题】尝试将对象数组传递给函数时出错【英文标题】:Getting Error when trying to pass an array of object to a function 【发布时间】:2012-04-13 14:30:17 【问题描述】:

我正在尝试传递Student 的数组

进入函数processStudent(string myFilename, Student* myArray, int &mySize)。 但它给了我不同类型的错误。

Student() 什么都不做,但我尝试为它们分配某种值,它仍然给出完全相同的错误消息:

主要是这样的:

// Create an array of students, with the size of theMax (256)
Student* arrayOfStudent= new Student[theMax];

// An integer that will keep track of actually how many students
// Because when we loop, we want to loop within the cell
// that actually have data or student.
int actualSize = 0;

// Invoke the helper function to set up the array of students
// It passed the arryOfStudent by reference, so the changes
// inside of the function will be reflected when it returns
processStudent(filename, arrayOfStudent, actualSize);

函数是这样的:

void processStudent(string myFilename, Student* myArray, int& mySize)

    // Something here, but removed still gives that error

//在班级学生的cpp文件中

Student::Student() 

    // Nothing here

错误信息:

new-host-2:csci135p1 george$ g++ -Wall -o csci135p2main csci135p2main.cpp
Undefined symbols for architecture x86_64:
  "Student::Student()", referenced from:
      _main in cc3fTXti.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

我一直在剥离和剥离我的代码,但这个错误不会消失。我想创建这个数组,并将它传递给 processStudent 函数,这样它就可以在读取文件时设置每一个。

【问题讨论】:

听起来像一个链接错误,你是如何构建的? 【参考方案1】:

你应该问自己一些可以帮助你的问题:

“如何创建 Student 的新实例?” 好吧,我这样做:Student* s = new Student(); - 它创建新对象并将对它的引用存储为指针 (Student*)

“那么如何创建一个包含 10 个 Students 的数组?” 好吧,它可能是一个指向新 Students 的指针数组,我可能不得不多次调用 new...如果这样想,你很容易得到这样的结果:

Student** students = new Student*[10];
for (int i = 0; i < 10; ++i)
    students[i] = new Student();

... 这意味着,当您清理它时,您必须在每个 Student* 上调用 delete,另外您还必须清理数组本身:在 Student** 上调用 delete[] -当你意识到丑陋的内存管理与指针数组连接时,它应该让你寻找更简单和更好的方法来实现它,因此你应该最终使用std::vector而不是数组,如果可能的话,使用对象而不是指针,如果不是,那么至少使用智能指针而不是裸指针。

【讨论】:

很好地解释了我的情况......真的很好。谢谢你。但是当然,在第一年的作业中,不允许使用向量。但是我可以更多地理解我的问题,并且处理指针非常棘手。 是的,我明白你的意思。编写这样的程序以了解基础知识很好......但问题是你应该意识到有更好的编码方法,所以不要太习惯它:) 我推荐你@ 987654321@,尤其是 0:12:50 的“Ghastly Style”部分和 0:27:30 的“Resources and Errors”部分......它会让你想得更多;)【参考方案2】:

第一个错误(自从我写这篇文章以来似乎已从问题中删除)告诉您processStudent 的第二个参数是一个指向指针Student**,而不是一个指针@ 987654323@。这很奇怪,因为您使用Student* 参数显示您的声明;你确定这是你的代码中的实际声明吗?你在某处有不同的声明吗?

第二个错误可能是因为您没有链接到包含构造函数定义的单元。您只使用一个源文件 (csci135p2main.cpp) 调用编译器,我猜您在不同的源文件中定义了构造函数。

【讨论】:

是的,第二个错误是因为我没有包含我的 O.O 类的源文件。不敢相信我在过去的 2 个小时里没有弄清楚。 这意味着你应该休息一下;)【参考方案3】:

有错误信息告诉你答案:

学生*'到'学生**'

更改processStudent()myArray参数的类型:

void processStudent(string myFilename, Student** myArray, int& mySize)


当一个数组被传递给一个函数时,它会衰减为一个指针:

void some_func(char* b) ...

char buf[100];
some_func(buf);

当您传递arrayOfStudent 时,数组衰减为指针,恰好该数组是指针数组,因此**


链接器抱怨它找不到Student 的默认构造函数的定义。该定义包含在Student.cpp 文件中,因此请编译所有源文件以解决链接器错误:

g++ -Wall -o csci135p2main csci135p2main.cpp Student.cpp

【讨论】:

你仍然可以使用myArray[1]【参考方案4】:

你最好使用 Student 的向量(最好只使用基本类型(int、char..)的数组和其他所有类型的向量)。

#include <vector>

std::vector<Student*> arrayOfStudent = new vector<Student*>();
/* ... */
processStudent(filename, arrayOfStudent, actualSize);

void processStudent(std::string& filename, vector<Student*>& arrayOfStudent, int& actualSize) 
/* ... */

我不确定这是否能解决你的问题,但至少这是一个更好的用途......

【讨论】:

std::vector&lt;Student*&gt; 是“泄漏”的秘诀。使用std::vector&lt;Student&gt;Student 实现移动语义,或vector&lt;shared_ptr&lt;Student&gt;&gt;vector&lt;unique_ptr&lt;Student&gt;&gt;【参考方案5】:

您的代码容易出错,难以维护异常不安全的 C++。 在现代 C++ 中,您应该使用 std::vector&lt;Student&gt;Student 类实现 移动语义,或者 vector&lt;shared_ptr&lt;Student&gt;&gt;vector&lt;unique_ptr&lt;Student&gt;&gt; 基于 Student 实例的所有权(共享与否) .

如果学生数组是输入/输出参数,你的函数原型应该是这样的:

void processStudent(const std::string & filename, std::vector<Student> & students);

相反,如果processStudent 函数创建了学生数组(例如,基于文件的内容),只需将其作为返回值返回(由于移动语义,这非常有效):

std::vector<Student> processStudent(const std::string & filename);

【讨论】:

以上是关于尝试将对象数组传递给函数时出错的主要内容,如果未能解决你的问题,请参考以下文章

将二维字符串数组传递给函数时出错 (C++)

将数组置于状态时出错 - React

将 JavaScript 对象数组传递给控制器

将二维数组传递给 double function_name 时出错

将变量传递给一个数组中对象的函数

将对象数组传递给构造函数[重复]