Я пытаюсь написать перегрузку для оператора = так, чтобы он позволял вам напрямую назначать один объект-ученик другому объекту-ученику. Таким образом, он скопирует все личные данные. Вот что я до сих пор.
.час
#ifndef PROJECT3HEADER_H
#define PROJECT3HEADER_H
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Student
{
public:
Student();
void Setlname(string lname);
void Setfname(string fname);
void SetAverage(float Average);
void SetLettergrade(char lettergrade);
void SetTestScore1(float score1);
void SetTestScore2(float score2);
void SetTestScore3(float score3);
void SetTestScore4(float score4);
void SetTestScore5(float score5);
string Getlname()const;
string Getfname()const;
float GetAverage()const;
char GetLetterGrade()const;
float GetScore1()const;
float GetScore2()const;
float GetScore3()const;
float GetScore4()const;
float GetScore5()const;
//void operator = (const Student & rhs);
Student operator=(const Student &rhs);
private:
string lname,fname;
float testScore[5];
float Average;
char lettergrade;
};
ostream & operator << (ostream &, const Student & pt);
//istream& operator >> (istream& in, Student& pt);
#endif
Studentmem.cpp
#include "Project3Header.h"
#include <iostream>
#include <string>
using namespace std;
Student::Student()
{
lname="";
fname="";
Average=0;
lettergrade=' ';
testScore[0]=0,testScore[1]=0,testScore[2]=0,testScore[3]=0,testScore[4]=0;
}
void Student::Setlname(string lname1){
lname=lname1;
}
void Student::Setfname(string fname1){
fname=fname1;
}
void Student::SetAverage(float average1){
Average=average1;
}
void Student::SetLettergrade(char lettergrade1){
lettergrade=lettergrade1;
}
void Student::SetTestScore1(float score1){
testScore[0]=score1;
}
void Student::SetTestScore2(float score2){
testScore[1]=score2;
}
void Student::SetTestScore3(float score3){
testScore[2]=score3;
}
void Student::SetTestScore4(float score4){
testScore[3]=score4;
}
void Student::SetTestScore5(float score5){
testScore[4]=score5;
}
string Student::Getlname()const {
return lname;
}
string Student::Getfname()const {
return fname;
}
float Student::GetAverage() const{
return Average;
}
char Student::GetLetterGrade()const{
return lettergrade;
}
float Student::GetScore1() const{
return testScore[0];
}
float Student::GetScore2() const{
return testScore[1];
}
float Student::GetScore3() const{
return testScore[2];
}
float Student::GetScore4() const{
return testScore[3];
}
float Student::GetScore5() const{
return testScore[4];
}
Student Student::operator=(const Student &rhs){
lname = rhs.lname;
fname = rhs.fname;
for (int i = 0; i < 5; i++){
testScore[i] = rhs.testScore[i];
}
return *this;
}
std::ostream& operator<<(std::ostream& out, Student const& obj)
{
out << "Lname: " << obj.Getlname() << "\n";
out << "fname: " << obj.Getfname() << "\n";
out << "Average: " << obj.GetAverage() << "\n";
out << "Grade: " << obj.GetLetterGrade() << "\n";
return out;
}
Но когда я пытаюсь использовать его в основном, я получаю сообщение об ошибке... ошибка чтения символов строки.
вот немного моего основного
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include "Project3Header.h"
using namespace std;
//Tyler Smith
void StdInfo(Student array[], int size);
Student * MakeStudentArray(int size);
int main(){
ifstream inData;
int size = 0;
int highsize = 0;
char data[65535];
inData.open("F:\\grade.dat");
if (!inData)
{
cout << "Error opening file.\n";
cout << "Perhaps the file is not where indicated.\n";
return 1;
}
while (inData.getline(data, 65535)) {
size++;
}
inData.close();
cout << size;
Student s1;
Student * ptArr;
ptArr = MakeStudentArray(size);
for (int i = 0; i < size; i++){
ptArr[i]= s1;
}
StdInfo(ptArr,size);
/* for (int i = 0; i < size; i++){
cout << ptArr[i].Getlname() << ptArr[i].Getfname(); //<< ptArr[i].Get() << endl;
}*/
cout << ptArr[2].Getfname();
return 0;
}
Student * MakeStudentArray(int size)
{
return new Student[size];
}
void StdInfo(Student array[], int size){
ifstream in;
in.open("F:\\grade.dat");
string fname1,lname1="";
int Score1, Score2, Score3, Score4, Score5=0;
for (int i = 0; i < size; i++) {
in >> lname1;
in >> fname1;
in >> Score1;
in >> Score2;
in >> Score3;
in >> Score4;
in >> Score5;
array[i].Setlname(lname1);
array[i].Setfname(fname1);
array[i].SetTestScore1(Score1);
array[i].SetTestScore2(Score2);
array[i].SetTestScore3(Score3);
array[i].SetTestScore4(Score4);
array[i].SetTestScore5(Score5);
array[i] = array[i + 1];
//for (int j = 0; j < 5; j++) {
//in >> array[i].testScore[j];
//}
}
}
Когда я попробую, это просто не сработает. Когда я делаю это в режиме отладки, он останавливается у оператора перегрузки и остается "ошибкой чтения rhs строки",
Суть вашей проблемы - не (нетрадиционный) оператор присваивания, а функция MakeStudentArray
.
Я жестко запрограммировал размер до 10, вместо того, чтобы читать его из файла и использовать
Student * MakeStudentArray(int size)
{
return new Student[size];
}
позаботиться о вызове delete [] ptArr;
после того, как я был сделан в основном (беспокоясь об исключениях, как я сделал), и все было хорошо.
Ваша версия выделяет студентов (возможно, всю кучу), а не массив.
Если я изменю код вопроса, который вы опубликовали в
for (int i = 0; i < size; i++){
ptArr[i].operator= (s1);
//^------- you said 0, right?
}
то у меня проблема. Это связано с тем, что цикл for предполагает, что "массив" является смежным, но ваша функция вводила массив точек, а не массив учеников, поэтому он вступает в доброту, только знает, где, когда он пытается перебрать "массив".
Использование моей версии предложения должно решить проблему, поскольку она выделяет массив, используя new[size]
а также упрощает удаление.
Изменить 1:
В остальном на main
размещенном сейчас, возможно, вы продолжаете пытаться установить ptArr[0]
несколько раз в цикле, но затем вызов StdInfo
попытается пройти "массив" и даст вам ошибку. Если вы хотите индексировать в массив, используя []
он должен быть смежным, поэтому функция выделения, MakeStudentInfo
прежнему будет причиной проблемы.
Edit2:
Теперь есть еще больше кода, посмотрите на свою функцию StdInfo
. Без дополнительных деталей он делает это:
for (int i = 0; i < size; i++) {
//...
array[i] = array[i + 1];
}
Что вы пытаетесь достичь здесь? Похоже, установить текущий array[i]
на то, чего мы еще не получили. Как только i
доберусь до size
i+1
вы покинете свой массив.
Удаление этой строки было бы хорошей идеей.
Оператор присваивания должен возвращать ссылку на назначенный объект, а не на копию. Также подумайте об использовании идиомы copy & swap
Student& Student::operator=(const Student &rhs){
MakeStudentArray
делает правильные вещи?Student&
неStudent