2

私はかなり混乱しています。私には、次の2つの実装は有効だと思います(ただし、構文にエラーがあります)が、どちらも機能させることができません。これは1年目のC++イントロクラスの宿題です。Vectorを使用することはできません(そうでなければ、ずっと前に行われます...)

すでにクラスを終了Studentしましたが、n人の生徒を格納するためのコンテナを作成する必要があります。私は次の2つのオプションを考えていました。

1)学生オブジェクトの配列を作成します。Student arrayOfStudents[20];

私の生徒のクラスはとてもシンプルです(行が多すぎるため、変更が異なります)。でもアイデアはこんな感じ…

class Student
{
    public:
    // Constructor for the Book class, take 6 arguments 
    Student(string myUID, string myLastName, string myFirstName, 
         string major, string age, string homeState, bool isWorking);
    ...
};

しかし、生徒の配列を作成しようとすると、このエラーメッセージが表示されます。

cs114p2main.cpp: In function ‘int main(int, char**)’:
cs114p2main.cpp:103: error: no matching function for call to ‘Student::Student()’
cs114p2Student.h:14: note: candidates are: Student::Student(std::string*)
cs114p2Student.h:11: note:                 Student::Student(std::string, std::string, std::string, std::string, std::string, bool)
cs114p2Student.h:7: note:                 Student::Student(const Student&)

2)また試してみました:各生徒を指す生徒ポインタの配列を作成します。 Student* ArrayOfStudents = Student[20];

私の質問は、なぜ方法1が機能しないのですか?そして、この場合、ポインターを使用する必要がありますか(メソッド2の行に沿ったもの)。

この配列を、各生徒を設定する関数に渡す必要があるためです。(何人の学生がそこに行くのかわかりません)。それで、それは私が学生の配列へのポインタを渡さなければならないことを意味しますか?その場合、方法1が機能することを本当に望んでいますが、学生ポインターの配列へのポインターを処理することは想像できません。の配列を返してdata[numOfData][numOfStudnet]、メインで実行する必要があると思っていましたが、どちらにしても、なぜこれでエラーが発生するのかを理解したいと思います。ありがとうございます。

編集:次の質問:調査を通じて、の配列のサイズをStudentパラメーターとして宣言する必要があることはわかっていますが、実行後にサイズしかわからない場合はどうなりますか?その場合、私の選択肢は何ですか?

4

2 に答える 2

3

Studentクラスにはコンストラクターが 1 つしかありません。つまり、

Student(string myUID, string myLastName, string myFirstName,  
     string major, string age, string homeState, bool isWorking); 

このため、既定のコンストラクターはコンパイラによって生成されません。また、1つも提供していないため(デフォルトのctor:引数なしで呼び出し可能なもの)、コンパイラーは配列を作成できません-要素に配置するには、デフォルトで構築可能なオブジェクトが必要です(配列を初期化します)。

修正するには、デフォルトの ctor を提供する必要があります。

Student();

Studentがどのように振る舞うと想定されているかに基づいて、自分で見つける必要がある振る舞い。

リストされたctorのすべてのパラメーターにデフォルト引数を提供することもできるため、パラメーターStudentを明示的に指定せずに呼び出すことができます-したがって、デフォルトctorとしての資格があります

デフォルトの ctor が実行可能でない場合は、より創造的になり、配列を動的に割り当て、既存のすべての要素を新しい要素にコピーし、必要に応じて指定された新しい要素をそれに割り当てる必要があります。std::vectorこれにより、本質的にコンテナの機能を再作成していることに注意してください。また、このアプローチを正しく行うのは非常に難しいことにも注意してください。特に基本を学んでいるだけなので、使用しないことをお勧めします。

さらに別のアプローチは、へのポインターの配列を作成するStudentことです。これにより、動的に作成するときにそれぞれを割り当てることができます。Student指しているオブジェクトにアクセスする前に、要素が null ポインターであるかどうかをテストする必要があります。

Student* students[20];

students[0] = new Student(/*list of actual parameter values*/);

if (student[0] != NULL) {
  students[0]->getName(); // assuming you have a member function getName()
}

注: インデックス 0 は説明目的でのみ使用されています。変数も使用できます (0 と 19 (両端を含む) の範囲内に収まる限り)。要素が 20 個ある場合でも、最大のインデックスは 19 であることに注意してください。カウントは0から始まります

于 2012-04-12T15:19:17.797 に答える
2

私の質問は、なぜ方法1が機能しないのですか?

Studentデフォルトのコンストラクター (引数のないコンストラクター) がないためです。デフォルトのコンストラクターは、コンストラクターが定義されていない場合にのみ、コンパイラーによって生成されます。少なくとも 1 つの引数を取るコンストラクターが定義されているため、既定のコンストラクターは存在しません。配列を宣言する場合:

Student arrayOfStudents[20];

Student存在しないデフォルトのコンストラクターを使用して、の 20 個のインスタンスが作成されています。

配列の使用を許可するデフォルトのコンストラクターを定義できますがStudent、名前や年齢などなしで a が存在することは意味がありますか?

または、次の配列を使用しますStudent*

Student* arrayOfStudents[20] = {}; // The '{}' will set all pointers to NULL.

編集:

学生の数が実行時までわからない場合:

// Get number of students somehow.
int numberOfStudents = ...;

// The '()' will set all pointers to NULL.
Student** arrayOfStudents = new Student*[numberOfStudents]();

delete各エントリarrayOfStudentsとそれ自体を覚えておいてくださいdelete[]arrayOfStudents

于 2012-04-12T15:19:36.627 に答える