2014-01-09 2 views
1

그래서 Attribute라는 객체를 만들었습니다.이 객체에는 전체 복사본과 빈 생성자가 있습니다. 그런 다음 Human이라는 다른 객체를 작성했습니다.이 객체에는 Attribute 객체가 들어 있습니다. 필자가 (전체 생성자를 사용하여) 휴먼 클래스를 빌드하려고하면 자동으로 Attribute 복사 생성자가 호출되며 이유가 없습니다. 여기 복사 생성자가있는 C++은 작동하지 않습니다.

코드입니다 :

char** d = new char*[3];  
    d[0] = new char[10]; 
    d[0] = "aa"; 
    d[1] = new char[10]; 
    d[1] = "bb"; 
    d[2] = new char[10]; 
    d[2] = "cc"; 

    Attribute *a = new Attribute(1.7, "blue", "white", "black", d, 3); 
    Human *h = new Human("Name", *a); 

내가 디버거를 사용하고이 라인에 도착 : 새 인간 ("이름", * A); 자동으로이 기능을 입력 :

Attribute::Attribute(Attribute& copy)  
{ 
    Attribute(copy.height, copy.eyeColor, copy.skinColor, copy.hairColor, copy.diseases, copy.numOfDiseases); 
} 

이 기능이 종료 된 후에 만, 그것은 인간 전체 생성자를 시작합니다 ...

난 당신이 나를 도울 수있을 것입니다 희망 .... 덕분에

+0

[규칙 3] (http://stackoverflow.com/questions/11024438/rule-of-three-in-c) 아마도 ... –

+1

정말 '인간'과 '속성'을 할당해야합니까? 힙에 (즉,'새'를 사용하고 포인터를 유지)? 내 감정은 당신이 자바를 사용하는 것과 C++을 사용하는 것이 좋지 않다는 것이다. –

+2

메모리 누수가 있습니다. 포인터에 익숙하지 않은 경우 (그리고 틀림없이 여러분이있을 때조차도) char *가 아닌 std :: string을 사용하십시오. – nvoigt

답변

7
Human *h = new Human("Name", *a); 
           ^----- Here it's passing in an Attribute by value 

따라서 Attribute 복사 생성자를 호출합니다.

1

복사 생성자가 아무것도 초기화하지 않습니다. 로컬 임시 객체를 만들고 파괴합니다. C++ 11에서

, 당신은 보이는대로, 다른 생성자에 작업을 위임 할 수는 일을하려고합니다 :

Attribute::Attribute(Attribute const & copy) : 
    Attribute(copy.height, copy.eyeColor, copy.skinColor, copy.hairColor, copy.diseases, copy.numOfDiseases) 
{} 

역사적으로, 당신은 다른 생성자의 코드를 복제해야 할 것이다, 또는 두 생성자가 호출하는 함수로 이동하십시오. 당신은 아마 또한 필요하지 않도록, 참조 생성자 인수를 할

복사 할 :

Human(std::string const & name, Attribute const & attribute); 

당신이 정말 필요하지 않는 한 당신은 또한 new을 피해야한다. 당신은 아마 더

Attribute a(1.7, "blue", "white", "black", d, 3); 
Human h("Name", a); 

같은 당신이 (당신이 다형성 때로는 개체가 현재 범위를보다 오래 할, 또는 일반적으로하기 때문에) 정말, new 필요합니까 원보다는 스마트 포인터 및 용기 등의 RAII 관리 유형을 사용하면 원하는 포인터를 사용하여 개체를 올바르게 삭제할 수 있습니다. 원시 포인터를 저글링하는 것은 메모리 누수 및 기타 재난을 대비하는 방법입니다. 인간에 대한 생성자 값

Human::Human(char* s, Attribute a) 

그것을위한 속성과 사용의 복사 생성자를 복사합니다 의해 초 매개 변수를 사용하는 경우

은, 따라서이다 -

1

A는 - A는 * 포인터 이다. 이 동작을 원하지 않으면 포인터로 매개 변수를 전달할 수 있습니다.

Human::Human(char* s, Attribute *a) 

과 같이 호출 :

Attribute *a = new Attribute(1.7, "blue", "white", "black", d, 3); 
Human *h = new Human("Name", a); // this works with pointer now. Pointer will be copied, but the class will remain in the same memory and wouldn't be copied anywhere. 

당신이 생각한다면, 동작이 정상 가치와 기능 등 유사합니다

void f1(int a){ a++; cout << a; } 
void f2(int *a){ *a++; cout << *a; } 

int b = 4; 
f1(b); // It copies the value of local b to parameter a, increments local parameter a of f1 and prints it; It will print 5 
cout << b; // b will remain the same. It will print 4 
f2(&b); // It copies pointer, but both pointers &b and a point to the same variable b from this scope, and it's value is not copied 
cout << b; // As we've worked with pointers, it was incremented in f2. It will print 5 

당신이 가지고 있습니다 모든 포인터의 책임을 다룬다. 수동으로 무언가를 만든 경우 삭제해야하는 부분과 누출이있는 부분을 잊지 마십시오. smart_pointers로 작업하는 것이 훨씬 쉽습니다.

관련 문제