2014-07-16 3 views
0

다음 코드에서 나는 int의지도와 클래스 A의 객체를 정의했습니다. funwithPointer와 funwithoutPointer의 두 함수를 정의했습니다. 보시다시피, 저는 클래스 객체에서 투표를 증가시키고지도에 추가하려고합니다. 내가 포인터를 사용하지 않고 객체를 선언 할 때 (funwithoutPointer) 2 번 투표를하면 3 번 호출 할 때 객체의 포인터를 사용하면 아무리 많은 함수를 호출해도 투표를 1 이상으로 늘릴 수 없습니다. 뭐가 문제 야 ? 문 객체에 대한 포인터의 혼동

  A a=m.find(i)->second; 
      a.change(); 

당신이 A 형의 새로운 객체를 생성하고 데이터 멤버를 증가

의 기능

void funwithoutPointer(map<int,A>& m){ 
for(int i=0;i<5;i++){ 
     if(m.find(i)==m.end()){ 
      A a= A(10); 
      a.change(); 
      m.insert(pair<int,A>(i,a)); 
     } 
     else{ 
      A a=m.find(i)->second; 
      a.change(); 
     } 
    } 
} 

에서

#include<iostream> 
#include<map> 
using namespace std; 
class A{ 
    public: 
     int x;int vote; 
     A(int a):x(a),vote(0){} 
     void change(){ 
      cout<<vote<<endl; 
      vote++;} 
}; 
void funwithPointer(map<int,A>& m){ 
for(int i=0;i<5;i++){ 
     if(m.find(i)==m.end()){ 
      A* a=new A(10); 
      a->change(); 
      m.insert(pair<int,A>(i,*a)); 
     } 
     else{ 
      A* a=&m.find(i)->second; 
      a->change(); 
     } 
    } 
} 
void funwithoutPointer(map<int,A>& m){ 
for(int i=0;i<5;i++){ 
     if(m.find(i)==m.end()){ 
      A a= A(10); 
      a.change(); 
      m.insert(pair<int,A>(i,a)); 
     } 
     else{ 
      A a=m.find(i)->second; 
      a.change(); 
     } 
    } 
} 
int main(){ 
    map<int,A> m; 
    funwithoutPointer(m); 
    funwithoutPointer(m); 
    funwithoutPointer(m); 
} 

답변

1

. 그것은지도의 해당 객체와 공통점이 없습니다. 다음 진술을 다음과 같이 변경하십시오.

  A &a = m.find(i)->second; 
      a.change(); 

지도에서 개체에 대한 참조를 사용하십시오. 또는 대신이 두 문으로 당신은 당신이 첫 번째 함수에서이 두 문장

  A &a = m.find(i)->second; 
      a.change(); 

과 문 사이에 볼 수 있듯이

  A* a=&m.find(i)->second; 
      a->change(); 

가 많습니다 다음과 같은 방법

  m.find(i)->second.change(); 

를 작성할 수 공유지.

A a=m.find(i)->second; 

그런 다음 a 이름을 지정하고,지도에서 객체의 복사본을 만들고있다 : 어느 당신은이

1

문제는이 라인에이 객체에 또는 포인터를 변경하는 개체에 대한 참조를 사용 해당 복사본을 수정하려고합니다. 수 당신이 코드는 빠른 (그리고 간단한 해결책), 꽤 효과가

A &a=m.find(i)->second; 

주의 사항 :

auto f = map.find(i); 
if(f == map.end()) 
    f = m.insert(std::make_pair(i, A(10))).first; 
f->second.change(); 

이 꽤되는 std::map::find() 완전히 불필요한 호출을 제거 간단한 솔루션은 참조를 사용할 수 비싼.

또 다른, 훨씬 더 효율적인 솔루션 (크리스 광대 - 젊은 덕분에) :

void funwithoutPointer(map<int,A>& m){ 
    for(int i=0;i<5;i++){ 
     map<int,A>::iterator iFind = m.find(i); 
     if(iFind==m.end()){ 
      A a(10); 
      a.change(); 
      m[i] = a; 
     } 
     else{ 
      iFind->second.change(); 
     } 
    } 
} 

이지도에 새로운 객체를하지 않을 경우 삽입합니다 :

auto f = map.lower_bound(i); 
if(f == map.end() || f->first != i) 
    f = m.insert(f, std::make_pair(i, A(10))); 
f->second.change(); 
+0

'find' 대신'lower_bound'를 사용하는 것이 더 빠르고, 결과가'end()'와 같거나 키가 'i'와 같지 않다면 d o 암시 된 삽입. :-) –

+0

따라서 :'auto f (map.find (i)); if (f == map.end() || f-> first! = i) m.insert (f, std :: make_pair (...)); 그렇지 않으면 ... ' –

+0

@Slava 내가 사용하면 어떻게됩니까?삽입 (쌍 (i, a)); change() 함수를 다시 호출 한 후. 즉, 업데이트 된 버전을 삽입합니다. – user3747190

0

은 당신이 원하는 것은 이것이다 찾거나 찾으면지도의 실제 객체를 수정할 수 있습니다.

관련 문제