2012-05-04 3 views
3

Bacterie*의 벡터 벡터를 포함하는 클래스 ZoneDeVie이 있습니다. Bacterie 클래스에는 int 값 energie (기본적으로 10으로 설정 됨)과 값을 인쇄하는 toString() 함수가 있습니다. ZoneDeVie 생성자에서 2D 테이블을 작성하고 각 셀에 기본 인스턴스 인 Bacterie을 채 웁니다. 그런 다음, 내 주요 방법으로, BacterietoString()을 테이블에 인쇄하여 테스트합니다. 어떤 이유로, 무작위의, 불쾌하게 커진 int (보통 3753512와 같은 것)를 반환합니다. 그러나 ZoneDeVie의 생성자에서 Bacterie의 toString() 메서드를 호출하면 main 메서드가 올바르게 출력됩니다. (전화로 "toString()"ZoneDeVie의 생성자와)C++ 멤버 변수 값은 인쇄 여부에 따라 변경됩니다.

#include <iostream> 
#include <sstream> 
#include <vector> 
using namespace std; 

class Bacterie { 
public: 
    Bacterie() { this->energie = 10; } 
    string toString() { 
     stringstream ss; 
     ss << "Energie: " << this->energie; 
     return ss.str(); 
    } 
protected: 
    int energie; 
}; 

class ZoneDeVie { 
public: 
    ZoneDeVie(int width, int height) { 
     Bacterie* bac = new Bacterie(); 

     // without this [following] line, the call to `toString` 
     // in the main method will return an obnoxiously-large value 
     //bac->toString(); 
     for (int i=0; i<height; i++) { 
      vector<Bacterie*> bacvec = vector<Bacterie*>(); 
      this->tableau.push_back(bacvec); 
      for (int j=0; j<width; j++) { 
       this->tableau[i].push_back(bac); 
      } 
     } 
    } 
    vector<vector<Bacterie*> > tableau; 
}; 

int main(int argc, char *argv[]) { 
    int x,y; 
    x = 9; y = 39; 
    ZoneDeVie zdv = ZoneDeVie(10,40); 
    cout << "zdv(" << x << "," << y << ") = " << zdv.tableau[x][y]->toString(); 

    return 0; 
} 

출력 :zdv(9,39) = Energie: 10

출력 (/ OA 통화 w에 ZoneDeVie의 생성자에서 "toString()") :zdv(9,39) = Energie: 4990504

왜 내가 toString() 메서드를 호출하여 main 메서드에서 호출하여 예상대로 작동해야합니까?

+0

에 대한 포인터로 초기화하는 것 같다? – mfontanini

+0

배열의 범위를 벗어나서 쓰거나 읽거나, 그렇지 않아야하는 메모리 일부 또는 초기화되지 않은 기본 유형이나 포인터에 액세스하려면 정의되지 않은 동작이 있어야합니다. – juanchopanza

+0

모든 포인터가 필요한 이유는 무엇입니까? – chris

답변

1

for 루프의 종료 조건이 서로 바뀝니다. 먼저 height을 통해 width 다음을 반복해야합니다

class ZoneDeVie { 
public: 
    ZoneDeVie(int width, int height) { 
     Bacterie* bac = new Bacterie(); 

     for (int i=0; i<width; i++) { 
      vector<Bacterie*> bacvec = vector<Bacterie*>(); 
      this->tableau.push_back(bacvec); 
      for (int j=0; j<height; j++) { 
       this->tableau[i].push_back(bac); 
      } 
     } 
    } 
    vector<vector<Bacterie*> > tableau; 
}; 

이 컴파일하고 정확한 출력을 제공합니다.

+0

공식적인 의미론은 여기에서 복사 구조를 필요로하지만, 표준은 명시 적으로 그것을 생략 할 수 있으며, 필자는 그것을 생략하지 않는 컴파일러에 대해 모른다. –

+0

ZoneDeVie :: ~ ZoneDeVie를 정의했으나 아무 것도하지 않습니다. ('{})) ... 어쨌든 ZoneDeVie 생성자에서 toString()을 호출하는 것이 왜 발생하는지에 대해 설명하는 것이 더 명확 할 수 있습니까? 주요 방법? – weberc2

+0

또한 ZoneDeVie :: ~ ZoneDeVie를 제거해도 결과에 전혀 영향을 미치지 않습니다. – weberc2

1

이 코드에는 몇 가지 문제점이 있습니다.

  1. Bacterie의 기본 생성자는 무엇을하는지 분명하지 않습니다.

  2. ZoneDeVie::tableau은 무엇이며 로컬 벡터 bacvec은 어떻게 사용되는지 명확하지 않습니다. 클래스 ZoneDeVie의 복사 생성자와 operator=이 (모두 main()에 사용되는)를 정의하는 방법

  3. 그것은 분명하지 않다.

  4. 그것은 당신이 소멸자`ZoneDeVie :: ~ ZoneDeVie`를 정의한 테이블의 모든 항목이 같은 Bacteriebac

+0

1) Bacterie :: Bacterie() {this-> energie = 10;} 2) ZoneDeVie :: tableau는 벡터입니다. 앞에서 설명한대로 'bacvec'는 ZoneDeVie 생성자에서 테이블을 채우는 데 사용되는 테이블의 행입니다. 3)'operator ='는 재정의 (override)되지 않고 ZoneDeVie는 파생 클래스가 아닙니다. 4) 맞습니다. – weberc2

+0

@ weberc2 : 이것은 질문의 일부가되어야하며 주석이 아닙니다. –

+0

@ DavidRodríguez-dribeas는 정보가 이미 사용 가능했거나 질문의 ​​내용에 따라 파생 될 수 있음을 나타냅니다. 그것을 반복하는 것은 어리석은 것처럼 보인다. 필자가 명확하지 않은 경우 편집 가능한 예제를 포함하도록 내 대답을 편집했습니다. – weberc2

관련 문제