2013-03-08 4 views
1

내가 형 B. 나는 다음과 같이이 일을하려고 한 방법의 포인터의 목록이 포함되어 내 클래스 A에 대한 복사 생성자를 만들려고하고의 목록 :C의 ++ 생성자를 복사 : 필드 포인터

class A 
{ 
private: 
    list<B*> myList; 
    list<B*>::iterator iter; 

public: 
    A() 
    { 
    } 

// Copy constructor 
A(const A &src) 
    { 
    myList.assign(src.myList.begin(), src.myList.end()); 
    } 

A& operator= (const A &src); 

}; 

A& A::operator= (const A &src) 
{ 
// do the copy 
myList.assign(src.myList.begin(), src.myList.end()); 

// return the existing object 
return *this; 
} 
A=a1; 

//call function that will change a1 

A a2(a1); 

//call function that will change a1 

그런 다음 A1 변경이 마지막 함수를 호출 한 후, 나는 A2가 너무 변경되었음을주의 사항 :

지금, 내 문제는 내가이 작업을 수행하는 경우이다. 복사 생성자가 이런 일이 발생하지 않도록해야한다고 생각했지만 코드에서 내가 뭘 잘못하고 있는지 알 수 없습니다.

+1

"a1이 바뀌면 a2도 변경되었습니다." 목록에 포함 된 요소에 적용됩니까? 요소를 수정하면 다른 객체에서도 수정됩니다. – Jack

+0

예, 의미는 – FranXh

+1

전화 번호부에 마을의 모든 사람의 이름, 전화 번호 및 주소를 상상해보십시오. 이제 친구에게 전화 번호부의 사본 *을주었습니다. 어떤 방식 으로든 그의 전화 번호부에있는 "Bob Jones"는 귀하의 * 전화 번호부에있는 "Bob Jones"와는 다소 차이가 있습니까? 예, 포인터 목록의 복사본은 그 자리에 꽤 많이 있습니다. – WhozCraig

답변

4

std::list은 포인터 목록입니다.
복사 생성자는 이러한 포인터 중 얕은 복사을 수행합니다. 복사 생성자 호출 후에 a1a2이라는 두 요소는 요소가 동일한 객체를 가리키는 목록입니다. 이러한 문제가 발생하지 않도록하려면
, 다음 중 하나를

  1. 는 단순히 딥 카피을 수행해야 std::list 구성원 또는
  2. 귀하의 복사 생성자의 객체가 아닌 포인터를 저장합니다.

하나의 포인터를 다른 포인터에 할당하면 얕은 사본이 수행됩니다. 간단히 말해 할당 후에는 두 포인터가 모두 같은 객체를 가리 킵니다. 코드는 대략 equivalent to입니다 :

#include<iostream> 

using namespace std; 

int main() 
{ 
    int i = 10; 
    int *ptr = &i; 
    int *ptr2 = ptr; 

    std::cout<<"\ni = "<<i; 
    std::cout<<"\n*ptr = "<<*ptr; 
    std::cout<<"\n*ptr2 = "<<*ptr2; 

    *ptr2 = 20; 

    std::cout<<"\ni = "<<i; 
    std::cout<<"\n*ptr = "<<*ptr; 
    std::cout<<"\n*ptr2 = "<<*ptr2; 

    return 0; 
} 

출력 :

i = 10 
*ptr = 10 
*ptr2 = 10 
i = 20 
*ptr = 20 
*ptr2 = 20 
+0

나는 이것을 이해할 수 있다고 생각하지만 목록의 기본 복사 생성자가 요소의 완전한 사본을 만들었다 고 믿었다. 이제 왜 이런 일이 일어나는지 보겠습니다.그럼 목록의 전체 복사본을 만드는 방법이 있습니까? – FranXh

+1

@FranXh : 뾰족한 각 요소에 별도로 메모리를 할당하고 해당 메모리를 가리키는 포인터를 만들고 목록에 새 포인터를 저장하십시오. 간단한 방법은 객체를 포인터가 아닌 요소로 저장하는 것입니다. –

2

현재 복사 생성자는 실제로 복사 생성자와 동일합니다. 사용자가 직접 구현하지 않으면 자동으로 생성됩니다 : 포인터 인 목록의 모든 요소를 ​​복사합니다. 목록 개체를 복사하고 원본을 변경 (예 : 요소 추가 또는 제거)하면 해당 변경 사항이 사본에 반영되지 않습니다. 그러나 목록에 저장된 객체에 대한 변경은 이고 목록에는 포인터 만 저장되기 때문에 복사본에이 반영됩니다. 당신이 그 행동을하지 않으려면 목록에서 실제 B 객체를 저장할 수 있습니다 B는 복사 가능한해야한다는 것을 의미 물론

list<B> mylist; 

.