0

私はの配列を渡そうとしています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
}

//クラスStudentの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関数に渡して、ファイルを読み取るときにそれぞれを設定できるようにします。

4

5 に答える 5

1

エラーメッセージがあなたに答えを伝えています:

Student*'から'Student**'</ p>

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

于 2012-04-13T14:33:33.623 に答える
1

あなたはあなた自身にあなたを助けることができるいくつかの質問をするべきです:

「Studentの新しいインスタンスを作成するにはどうすればよいですか?」
さて、私はこのようにします:Student* s = new Student();-それは新しいオブジェクトを作成し、それへの参照をポインタとして保存します(Student*

「では、10秒の配列を作成するにはどうすればよいStudentですか?」
まあ、それはおそらく新しいStudentsへのポインタの配列になるでしょう、そして私はおそらく何度も呼び出さnewなければならないでしょう...このように考えることによってあなたは簡単に次のようなものになってしまうでしょう:

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

...つまり、クリーンアップするときは、deleteすべてStudent*のプラスを呼び出す必要があります。さらに、配列自体もクリーンアップする必要があります。呼び出しますdelete[]-Student**そして、醜いメモリ管理がポインタの配列に接続していることに気付いたとき、実装のより簡単でより良い方法を探す必要があります。したがって、std::vector可能であれば、配列の代わりにオブジェクトを使用し、不可能な場合は、少なくとも裸のポインターではなくスマートポインターを使用する必要があります。

于 2012-04-13T14:48:39.703 に答える
1

最初のエラー(これを書いたので質問から削除されたようです)は、の2番目のパラメーターがprocessStudentポインターからポインターでありStudent**、ポインターではないことを示していますStudent*Student*パラメータを使用して宣言を表示するので、これは奇妙なことです。それがあなたのコードからの実際の宣言であると確信していますか?どこかに別の宣言がありますか?

2番目のエラーは、コンストラクターの定義を含むユニットにリンクしていないことが原因である可能性があります。1つのソースファイル()だけでコンパイラを呼び出してcsci135p2main.cppおり、別のソースファイルでコンストラクタを定義していると思います。

于 2012-04-13T14:38:34.367 に答える
0

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) {
/* ... */
}

それがあなたの問題を解決するかどうかはわかりませんが、少なくともそれはより良い使用法です...

于 2012-04-13T14:41:43.853 に答える
0

あなたのコードはバグが発生しやすく、例外を維持するのが難しく、安全ではないC++です。最新のC++では、移動セマンティクスを実装するクラスstd::vector<Student>で、またはインスタンスの所有権(共有されているかどうかに関係なく)に基づいて、を使用する必要があります。Studentvector<shared_ptr<Student>>vector<unique_ptr<Student>>Student

また、student配列が入力/出力パラメーターである場合、関数プロトタイプは次のようになります。

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

代わりに、processStudent関数が(たとえば、ファイルの内容に基づいて)学生の配列を作成する場合は、それを戻り値として返すだけです(これは、移動セマンティクスのおかげで非常に効率的です)。

std::vector<Student> processStudent(const std::string & filename);
于 2012-04-13T15:01:16.277 に答える