2015-01-30 5 views
0
class Wood { 
public: 
    Wood(); 
    Wood(const Wood&); //copy constructor 
    ~Wood(); 

private: 
    string price; 
}; 

Wood::Wood(const Wood& orig) { 
    price(orig.price); **//error, why?** 
} 

Wood::Wood(const Wood& orig) : price(orig.price) { //rigth 

} 

만약 내가 구조체 초기화를 사용하고 정확했다면. 그러나 "price (orig.price)"를 사용하면 오류가 발생하는 이유는 무엇입니까?사본 구조에 관하여

+0

왜 오류가 아니어야한다고 생각합니까? –

+0

@AntonSavin, 왜냐하면 나는 "price (orig.price)"의 사용법이 std :: string 클래스의 copy 생성 함수를 사용할 것이라고 생각하기 때문이다. –

답변

1

가격이 이미 구성되어 있기 때문에 올바르지 않습니다. 이미 생성 된 경우 복사 생성자라고 부를 수 없습니다.

다음과 같이해야합니다. price = orig.price;

1

컴파일 오류를 검사하면 이유가 표시됩니다. 멤버 초기화 자 목록에서 price(orig.price)은 멤버 변수 pricedirect initialization이고 값은 orig.price입니다. 복사 생성자의 본문에서 price(orig.price)std::string을 허용하는 std::string의 오버로드 된 operator()에 대한 호출입니다. 그러한 과부하가 없으므로 컴파일 오류가 발생합니다.

4

생성자의 함수 본문 (여는 중괄호와 닫는 중괄호 사이의 부분)은 다른 함수의 본문과 다르지 않습니다. 컴파일을 기대 하시겠습니까?

std::string a, b; 
a(b); // <--- this line? 

아니요, 물론 아닙니다. 컴파일하기 위해서 std::stringoperator()과 같은 무언가를 필요로합니다. 또 다른 문자열을 필요로합니다. 그건 없어.

초기화 목록의 코드가 다릅니다. 초기화 목록의 표현식은 함수 본문 내부의 표현식처럼 일반 명령문으로 해석되지 않습니다. 그것들은 초기화 (예 : 생성자 호출)로 해석됩니다. 즉 이미 완료 되었기 때문에, price의 유형을 지정할 필요가 없습니다 것을 제외하고

std::string price(orig.price); 

: 그래서, 초기화 목록에서이 :

: price(orig.price) 

이 같은 성명에 동일 클래스 정의에서.

생성자 본문에 도착할 때까지 모든 멤버가 이미 초기화되었으므로 생성자 본문 내부에서 멤버 초기화를 수행 할 수 없습니다. 그래서 초기화 목록이 필요합니다. 물론 생성자 본문에서 할당을 수행 할 수 있습니다.

price = orig.price; 

하지만 초기화와 다릅니다. 일부 유형 (예 : const 구성원, 참조 구성원 또는 기본 생성자가없는 구성원)에서는 작동하지 않습니다. 그리고 당신이 먼저 (기본 생성자로) 생성하고 할당하고 있기 때문에 일부 유형에서는 효율성이 떨어질 수 있습니다. 그러나 많은 유형의 경우 기본 구성 비용이 거의 들지 않으므로 별 문제가되지 않습니다.

+0

감사합니다. 귀하의 분석은 매우 상세했으며 이유를 알았습니다. –