0

我想的Student试图对象的数组传递给函数

数组传递到功能processStudent(string myFilename, Student* myArray, int &mySize)时得到错误。 但它给了我不同的错误。

学生()什么也不做,但我想给它们分配某种价值,但它仍然给出确切的同样的错误信息:

在主我有这样的:

// 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

听起来像一个链接错误,你怎么建设? – Shep 2012-04-13 14:36:23

回答

1

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

“如何创建学生的新实例?”
嗯,我不喜欢这样写道:Student* s = new Student(); - 它创造了新的对象和referrence存储到它作为一个指针(Student*

“那么,如何创造的10 Student秒的阵列?”
那么,它可能会是指向新Student组成的数组,我可能要打电话不止一次new更多...通过这样的想法,你会很容易地像这样结束:

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

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

+0

我的情况很好的解释...真的很好。谢谢。但是,当然,第一年的作业,没有矢量是允许的..但我可以更多地理解我的问题,处理指针是非常棘手的。 – George 2012-04-13 14:56:21

+1

是的,我理解你的观点。编写这样的程序是为了理解基础知识,这很好,但是问题是你应该认识到有更好的代码编写方法,所以不要太习惯它:)我建议你[本讲座](http://www.youtube.com/watch?v=OB-bdWKwXsU),特别是0:12:50部分叫做“Ghastly Style”,0:27叫“资源与错误”部分:30 ...它会让你更多地思考它;) – LihO 2012-04-13 15:21:56

1

有错误信息,告诉你答案:

Student*’ to ‘Student**’

更改myArray争执中processStudent()类型:

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

+0

你仍然可以使用'myArray [1]'。 – hmjd 2012-04-13 14:52:16

1

的第一个错误(这似乎已经从因为我写了这个问题去掉)是告诉你,第二个参数processStudent是一个指针指针,Student**,而不是指针,Student*。这很奇怪,因为你用Student*参数显示你的声明;你确定这是你的代码的实际声明吗?你有不同的声明吗?

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

+0

是的,第二个错误是因为我没有包含我的OO类的源文件。简直不敢相信在过去的2个小时里我怎么也弄不清楚。 – George 2012-04-13 14:41:16

+1

这意味着你应该得到一些休息;) – zmo 2012-04-13 14:44:48

0

你最好使用学生的向量(更喜欢使用数组只与基本类型(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) { 
/* ... */ 
} 

我不知道是否会解决你的问题,但至少这是一个更好的利用......

+0

不能使用'矢量',但是谢谢.. – George 2012-04-13 14:43:33

+2

'std :: vector '是“leaktrocity”的秘诀。使用'std :: vector '''学生'执行_move semantics_或'vector >'或'vector >'。 – 2012-04-13 14:54:18

+0

我的歉意,你是对的;) – zmo 2012-04-13 16:40:25

0

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

而且你的函数原型应该是这样的,如果学生阵列是一个输入/输出参数:

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

相反,如果processStudent函数创建学生的阵列(例如,基于文件的内容),只是返回它作为返回值(这是非常有效的感谢移动语义):

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