2016-10-27 6 views
0

여기 내 프로그램이 있습니다. 나는 타입 Student 객체를 만들고 나서, 학생에게 아이템을 "체크 아웃"하게해야합니다. 그리고 오버로드 된 연산자를 사용하여 사용자가 해당 항목을 체크 아웃하도록합니다.오버로드 된 덧셈 연산자를 사용하는 데 어려움이 있습니다.

MAIN.CPP : 나는 시도하고 최소한의 단순화이 프로그램을 유지하기 위해 헤더 파일 내 모든 클래스되어 정의를 정의

#include <iostream> 
#include "Student.h" 

using namespace std; 

int main() { 

    Student s(54000, "JOHN", "DOE"); 

    cout << "main:" << endl << (s + "Frisbee") << endl << endl; 

    system("pause"); 

    return 0; 

} 

.

Student.h :

#ifndef STUDENT_H 
#define STUDENT_H 

#include <fstream> 
#include <string> 
#include <iostream> 

using namespace std; 

class Student { 

public: 

    string firstName; 
    string lastName; 
    int id; 
    int itemsCheckedOut; 
    int size; 
    string *array; 

    Student(int id = 0, string firstName = "", string lastName = "") { 
     Student::firstName = firstName; 
     Student::lastName = lastName; 
     Student::id = id; 
     itemsCheckedOut = 0; 
     size = 10; 
     array = new string[size]; 
    } 

    Student(const Student &other) { 
     itemsCheckedOut = other.itemsCheckedOut; 
     array = new string[itemsCheckedOut]; 
     for (int i = 0; i < itemsCheckedOut; i++) { 
      array[i] = other.array[i]; 
     } 
    } 

    ~Student() { 
     delete[] array; 
     array = NULL; 
    } 

    Student &operator=(const Student &rhs) { 
     if (this != &rhs) { 
      firstName = rhs.firstName; 
      lastName = rhs.lastName; 
      id = rhs.id; 
      itemsCheckedOut = rhs.itemsCheckedOut; 
      delete[] array; 
      array = new string[size]; 
      for (int i = 0; i < itemsCheckedOut; i++) { 
       array[i] = rhs.array[i]; 
      } 
     } 
     return *this; 
    } 

    void CheckOut(const string &item) { 
     array[itemsCheckedOut] = item; 
     itemsCheckedOut++; 
    } 

    friend ostream &operator<<(ostream &output, const Student &student) { 
     output << student.id << " " << student.firstName << " " << student.lastName << endl; 
     if (student.itemsCheckedOut != 0) { 
      output << student.itemsCheckedOut; 
      for (int i = 0; i < student.itemsCheckedOut; i++) { 
       output << " " << student.array[i] << endl; 
      } 
     } 
     else { 
      output << 0; 
     } 
     return output; 
    } 

    const Student operator+(const string &item) { 
     Student s; 
     s = *this; 
     s.CheckOut(item); 
     cout << "class:" << endl << s << endl << endl; 
     return s; 
    } 

}; 

#endif 

출력 : 당신이 볼 수 있듯이

class: 
54000 JOHN DOE 
1 Frisbee 

main: 
-858993460 
1 Frisbee 

주에서의 잘못된 일을 출력한다. 첫 번째 이름과 성을 공백 다음에 ID를 출력하는 대신 숫자 -858993460을 출력합니다. 이것은 일종의 메모리 누출 문제가 될 것입니다.하지만 저는 확실히 복사 생성자, 오버로드 된 대입 연산자 및 deconstructor가 모두 올바르게 정의되어 있지만 여러분은 그것들을 살펴볼 수 있습니다.

내가 필사적으로 여기에서 필사적으로되고있는 것에 따라 나는 조금의 도움도 완전히 감사 할 것이다. 감사.

+0

수정 해 주셔서 감사합니다. – Jacob

답변

0

(나는이 프로젝트에 대해 질문을 게시이 마지막으로 언급) :

Student(const Student &other) { 
    itemsCheckedOut = other.itemsCheckedOut; 
    array = new string[itemsCheckedOut]; 
    for (int i = 0; i < itemsCheckedOut; i++) { 
     array[i] = other.array[i]; 
    } 
} 

을하지만 당신은 몸에있는 모든 학생의 필드를 복사하는 것을 잊지. 기본 복사 생성자를 대체하므로 할당 연산자처럼 모든 데이터 복사를 수동으로 실행해야합니다.

+0

와우, 나는 이것을 잡지 못했다고 믿을 수 없다. 복사 생성자가 동적 배열이나 그 밖의 것에 만 사용된다고 생각한 것 같습니다. 도와 주셔서 감사합니다. :) – Jacob

0

문자열 * 배열을 std :: vector로 바꿔야합니다. 그것은 당신을 위해 메모리 관리를 처리 할 것이고, 당신이 현재 사용하고있는 수작업 메모리 관리보다 훨씬 쉽고 오류가 적은 코드로 만들 것입니다. 항목을 추가 할 때 할당을 수행 할까 걱정되는 경우 초기 크기를 10으로 예약 할 수 있습니다 (문제가되지 않는 작은 크기의 데이터로도 가능함).

+0

이것은 학교 수업 중 하나에 대한 과제이며, 동적 문자열 배열을 사용해야한다는 가이드 라인에 설명되어 있습니다. – Jacob

+0

@Jacob 단어에 능숙하고 선생님이 유머 감각을 가지고 있다면, std :: vector는 내부적으로 동적 배열을 가지고 있으므로 간접적으로 사용하고 있습니다. :) – Lehu

+0

Lol, 그게 쉽다면 ... : P하지만 실제로, 동적 문자열 배열로 작동시키는 법을 알고 싶습니다. 왜 이렇게하는지 잘 모르겠습니다. – Jacob

1

실제 operator+가 올바르게 보입니다.

  • 는 복사 생성자는 size, id, 또는 이름을 설정하지 않습니다하지만 오작동을 일으킬 것이다 당신의 복사 생성자와 대입 연산자의 버그가 있습니다.
  • 복사 생성자는 [itemsCheckedOut]이 아니라 [size] 개의 항목을 할당해야합니다.
  • 할당 연산자는 size을 복사하지 않습니다.
  • 할당 연산자는 차원이 이전 크기 인 새 배열을 할당하므로 즉각적인 버퍼 오버플로가 발생할 수 있습니다.
  • checkOut 함수는 size을 초과하여 쓰지 않는지 확인하지 않습니다. 이 경우를 감지하고 체크 아웃을 거부하거나 더 많은 공간을 할당해야합니다. 그것은 복사 생성자를 호출
+0

도움 주셔서 감사합니다 @ M.M. 그리고 실제로 CheckOut이 크기를 초과하여 쓸 때를 감지 할 수있는 기능을 추가해야합니다. 팁 고마워. :) – Jacob