2017-11-21 1 views
0

Ivor Horton의 "Beginning Visual C++ 2010"에서 작성한 코드가 있습니다. 특히 Ex10_02.cpp는 Person.h를 사용합니다.<for class>를 사용하여 sort() 문제를 해결했습니다.

sort 함수가 내 클래스 개체에서 작동하지 않습니다. 이름을 입력하고 Enter 키를 누를 때 입력 된 순서대로 이름 목록이 출력되고 sort() 함수가 호출 된 후 이름이 다시 화면에 출력됩니다. 두 번째 이름을 기준으로 정렬해야합니다. 그러나 그들은 처음에 내가 입력 한 순서대로 출력됩니다.

컴파일 오류가 발생하지 않습니다. 내 연산자에 대한 <() 연산자를 테스트하고 Person 클래스의 두 객체를 비교할 때 작동합니다. 그러나 다시 Person 객체의 벡터에 대한 sort() 함수가 제대로 작동하지 않습니다. 왜 이런 일이 벌어지고 있는지 더 이상 생각할 필요가 없습니다. 모든 통찰력이 환영받을 것입니다.

코드는 다음과 같다 :

// Ex10_02 
// storing objects in a vector 

#include <iostream> 
#include <vector> 
#include <algorithm> 
#include "Person.h" 

using namespace std; 

int main() 
{ 
    vector<Person> people;     // Vector of Person objects 
    const size_t maxlength(50); 
    char firstname[maxlength]; 
    char secondname[maxlength]; 
    vector<int> numbers; 

    // input all the people 
    while(true) 
    { 
     cout << "Enter a first name or press Enter to end:"; 
     cin.getline(firstname, maxlength, '\n'); 
     if(strlen(firstname) == 0) 
      break; 
     cout << "Enter the second name: "; 
     cin.getline(secondname, maxlength, '\n'); 
     people.push_back(Person(firstname, secondname)); 
    } 

    // Output the contents of the vector 
    cout << endl; 
    auto iter(people.begin()); 
    while(iter != people.end()) 
     iter++->showPerson(); 

sort(people.begin(), people.end()); 
    cout << endl; 
    for(auto i = 0; i < people.size(); i++) 
    { 
     people[i].showPerson(); 
    } 

    cout << endl; 
    for(auto i = 0; i < people.size(); i++) 
    { 
     people[i].showPerson(); 
    } 
    cout << endl; 
    cout << "Is people[0] < people[1] ?" << endl; 
    if(people[0] < people[1]) 
    { 
     cout << "YES" << endl; 
     people[0].showPerson(); 
     people[1].showPerson(); 
    } 
    else 
    { 
     cout << "NO" << endl; 
     people[1].showPerson(); 
     people[0].showPerson(); 
    } 
    cout << endl; 
    int myints[] = {32,71,12,45,26,80,53,33}; 
    vector<int> myvector (myints, myints+8);    // 32 71 12 45 26 80 53 33 
    for(int i = 0; i < 8; i++) 
    cout << myvector[i] << endl; 
    cout << endl; 
    // using default comparison (operator <): 
    sort(myvector.begin(), myvector.end());   //(12 32 45 71)26 80 53 33 
    for(int i = 0; i < 8; i++) 
    cout << myvector.at(i) << endl; 
    return 0; 
} 

//----------------------------------------------------------------------- 

Person.h : 너무 일찍 돌아가, 당신이 잘못 &p == this 확인이

// Assignment operator 
Person& operator =(const Person& p) 
{ 
    // deal with p = p assignment situation 
    if (&p != this) 
    { 

     delete[] firstname; 
     delete[] secondname; 
     initName(p.firstname, p.secondname); 
    } 

    return *this; 
} 

과 :

// A class defining people by their names 
//#pragma once 
#ifndef PERSON_H_INCLUDED 
#define PERSON_H_INCLUDED  
#include <cstring> 
#include <iostream> 
using namespace std; 

class Person 
{ 
public: 
    // Constructor, includes no-arg constructor 
    Person(const char* first = "John", const char* second = "Doe") 
    { 
     initName(first, second); 
    } 
    // Copy constructor 
    Person(const Person& p) 
    { 
     initName(p.firstname, p.secondname); 
    } 
    // Destructor 
    ~Person() 
    { 
     delete[] firstname; 
     delete[] secondname; 
    } 
    // Assignment operator 
    Person& operator =(const Person& p) 
    { 
     // deal with p = p assignment situation 
     if(&p == this) 
     { 
      return *this; 

      delete[] firstname; 
      delete[] secondname; 
      initName(p.firstname, p.secondname); 
      return *this; 
     } 
    } 
     // Less-than operator 
     bool operator <(const Person& p) 
     { 
      int result(strcmp(secondname, p.secondname)); 
      if(result < 0 || result == 0 && strcmp(firstname, p.firstname) < 0) 
       return true; 
      return false; 
     } 
     // output a person 
     void showPerson() const 
     { 
      cout << firstname << " " << secondname << endl; 
     } 

private: 
    char* firstname; 
    char* secondname; 

    // private helper function to avoid code duplication 
    void initName(const char* first, const char* second) 
    { 
     size_t length(strlen(first)+1); 
     firstname = new char[length]; 
     strcpy_s(firstname, length, first); 
     length = strlen(second) + 1; 
     secondname = new char[length]; 
     strcpy_s(secondname, length, second); 
    } 
}; 
#endif // PERSON_H_INCLUDED 
+1

조건을, 당신의 비교 연산자 const하게 사용할 수 있습니다

if (result < 0 || (result == 0 && strcmp(firstname, p.firstname) < 0)) 

<'기능은 동일 '결과 <0 || (결과 == 0 && 결과 <0)'. 아무런 문제가 보이지 않습니까? –

+1

그리고 사용자 정의 비교 연산자에 대한 정렬 함수와 호출을 포함하여 디버거를 사용하여 한 번에 한 줄씩 코드를 실행할 때 어떤 관측을 했습니까? 디버거를 사용하여 프로그램의 실행을 완전히 분석하는 방법을 알고 있습니까? 결국, 디버거를 사용하는 방법을 아는 것은 모든 C++ 개발자에게 필수적인 기술입니다. –

+1

다음은 버그를 찾는 데 도움이되는 팁입니다. 작업 비교 연산자는'sort()'가 올바르게 작동하기에 충분하지 않습니다. 예를 들어, 벡터의 순서가 틀린 경우,'sort()'함수는 요소를 교환 할 수 있어야합니다. 이것은 대입 연산자를 사용한다는 것을 의미합니다. 이제 버그가 보일 때까지 할당 담당자를 계속 쳐다보십시오. –

답변

1

은 다음과 같이 귀하의 할당 연산자를 변경 else 경로에 대한 리턴 경로가 없습니다 (끝에 있음). 이미에 @StoryTeller에 의해 지적처럼

그리고 당신의 비교 연산자 : 당신은 또한`연산자 등 std::string

+0

감사합니다. 나는 할당 연산자를 보지 못했을 것이다. –

+0

움직일 수없는 객체의 목록을 가지고 있기 때문에'sort'는 새로운 값을 할당함으로써 움직입니다. –

관련 문제