Почему в C ++ я не могу объявить динамический c массив объектов с разбитыми на части конструкторами? - PullRequest
2 голосов
/ 15 марта 2020

Я пытаюсь создать простую программу, которая будет отображать имена студентов из массива объектов, называемых «Студент», я знаю, что это легко сделать с помощью векторов, но я бы хотел сделать это с помощью массива Dynami c. Мой код:

class Student {
public:
  string name;
  Student(string name){
    this->name = name;
  }
};

void DisplayStudentsNames(Student array[],int length) {
  for(int i=0;i<length;i++){
    cout << array[i].name << endl;
  }
}

int main(int argc, char** argv) {
  Student ** array = new Student *[3];
  array[0] = new Student("Michael");
  array[1] = new Student("Tom");
  array[2] = new Student("Timmy");
  DisplayStudentsNames(*array,3);
  return 0;
}

Я не уверен, почему он не работает, он компилируется, но программа просто «перестает отвечать» после отображения имени первого студента. Интересно, в чем проблема, я прочитал здесь , что если в Class нет никакого конструктора с нулевым аргументом, вы не можете динамически создавать массив динамических c объектов, интересно, почему это так? Я просто назначаю новые объекты указателям (в C# это нормальный способ создания класса).

1 Ответ

1 голос
/ 15 марта 2020

Ваша проблема здесь

DisplayStudentsNames(*array,3);

То, что вы фактически передаете DisplayStudentNames(), вот первый элемент - массив array. Проблема в том, что array[0] это не массив, это указатель на один объект. Поэтому, когда вы пытаетесь повторить его, вы получаете неопределенное поведение, исключение будет наилучшим случаем scienorio здесь (как вы видели с вашим бесконечным l oop).

Вы можете исправить это, изменив

DisplayStudentsNames(*array,3);

до

DisplayStudentsNames(array,3);

и DisplayStudentsNames до Student**

Также это не сработает:

cout << array[i].name << endl;

Каждый элемент в array является указателем на объект Student, а в C ++ для доступа к объекту через указатель требуется использование оператора -> (поэтому вместо него array[i]->name).

Примечание:

Student(string name){
    this->name = name;
  }

Это плохо для C ++, вместо этого используйте списки инициализаторов для задания элементов при создании, так как он позволяет оптимизировать компилятор и его легче читать

...