2009-10-18 5 views
14

클래스의 복사 생성자를 정의 할 때 기본 생성자를 명시 적으로 정의해야합니까 ?? 이유를 알려주세요.복사 생성자와 기본 생성자

예 :

또한
class A 
{ 
    int i; 

    public: 
      A(A& a) 
      { 
       i = a.i; //Ok this is corrected.... 
      } 

      A() { } //Is this required if we write the above copy constructor?? 
};  

우리는 복사 생성자가 아닌 다른 클래스의 다른 매개 변수가있는 생성자를 정의하는 경우, 우리는 또한 기본 생성자를 정의해야합니까? 복사 생성자없이 위의 코드를 고려하고 나는 다음과 같은 프로그램을 작성 답변을 본 후 ....

A(int z) 
{ 
    z.i = 10; 
} 

괜찮 니로 교체하십시오.

#include <iostream> 

using namespace std; 

class X 
{ 
    int i; 

    public: 
      //X(); 
      X(int ii); 
      void print(); 
}; 

//X::X() { } 

X::X(int ii) 
{ 
    i = ii; 
} 


void X::print() 
{ 
    cout<<"i = "<<i<<endl; 
} 

int main(void) 
{ 
    X x(10); 
    //X x1; 
    x.print(); 
    //x1.print(); 
} 

이 프로그램은 기본 생성자없이 제대로 작동하는 것 같습니다. 이 사건이 왜 그런지 설명해주십시오. 나는이 컨셉과 정말로 혼동 스럽다 .....

+2

혼란스러워. 아래의 해답은 정확하지만 복사 생성자는 아닙니다. 정확히 어디서 '내가'복사하고 있니? 당신은 일반적으로 잘못된 행동 인 오른쪽을 수정하고 있습니다. 'A (const A & rhs) : i (rhs.i) {}'를 실행해야합니다. 즉, 오른쪽의'i'를 A의'i'의 인스턴스로 복사해야합니다. 매개 변수가 상수로 전달된다는 점에 유의하십시오. x = 3과 같은 것을 말할 때 3이 변경되어서는 안되기 때문입니다. 또한 작은 데이터 유형에서는 참조가 더 느려질 수 있기 때문에 일반적으로 숫자 유형은 값이 아닌 참조로 전달됩니다. – GManNickG

+0

와우 .... 의견을 보내 주셔서 감사합니다 ... 오늘 아침에 생성자를 공부하기 시작한 이래로 혼란스러워했던 생성자의 ": i (rhs.i)"부분에 대한 혼란을 해결했습니다. –

+1

최신 프로그램은 기본 생성자를 전혀 사용하지 않습니다. 이런 이유로, 당신은 그것을 정의 할 필요가 없습니다. 그게 전부입니다. – AnT

답변

33

예. 명시 적으로 클래스에 대한 생성자를 명시 적으로 선언하면 컴파일러에서 암시 적 기본 생성자 제공을 중단합니다. 여전히 기본 생성자가 필요한 경우 명시 적으로 선언하고 정의해야합니다.

P. 기본값 인 생성자 인 복사 생성자 (또는 변환 생성자 또는 다른 생성자)를 작성할 수 있습니다. 복사 생성자가 동시에 기본 생성자에있다 위의 예에서

// Just a sketch of one possible technique  
struct S { 
    S(const S&); 
    S(int) {} 
}; 

S dummy(0); 

S::S(const S& = dummy) { 
} 

: 새로운 생성자는 해당 범주에 속하는 경우, 추가 기본 더 이상 생성자 : 예를 들어

를 제공 할 필요가 없습니다 .

+0

"기본 생성자이기도 한 복사본 생성자를 작성할 수 있습니다." 방법? – dalle

+0

예를 들어 복사 구속 자에 기본 인수를 추가합니다. 내 응답에 추가 한 예를 참조하십시오. – AnT

+0

편집 한 질문을 취소 해 주실 수 있습니까? 코드가 기본 생성자를 정의하지 않고 잘 작동합니다 .. –

3

둘 다 정의 할 필요는 없습니다. 그러나 클래스에 대한 생성자를 정의한 후에는 모든 기본 생성자를 사용할 수 없게됩니다. 따라서 복사없이 복사하고 생성하지 않으려면 기본값이 아닌 (즉, 명시적인) 기본 (즉 매개 변수 없음) 생성자를 정의해야합니다.

복사 생성자를 정의하는 경우 대개 할당 연산자도 재정의해야합니다.

+0

"default"라는 단어가 오버로드되어 혼란 스럽습니다. 뿐만 아니라 당신의 과부화 된 디폴트의 의미는 생성자와 함께 사용하도록 예약 된 또 다른 키워드 인 "explicit"이라는 단어로 설명되었습니다! 대신 합성을 사용할 수 있습니다 (원하는 경우 z로). :) – Troubadour

+0

단어 "기본값"의 과부하는 고의적이었습니다. 당신이 말로 표현할 수 없다는 것은 슬픈 일입니다. "명백한"단어에 관해서는 C++ 언어 내에서 특수한 의미가 존재한다고해서 영어 내의 기존 의미가 무효화되는 것은 아닙니다. 그리고 "합성 된"것에 관해서 - 나는 목표가 이해되어야한다고 생각 했습니까? – Steve314

1

AndreyT에 따르면 복사 생성자를 포함하여 명시 적으로 생성자를 선언하면 컴파일러에서 암시 적으로 기본 생성자를 선언하거나 정의하지 않습니다.

항상 문제가되는 것은 아닙니다.

클래스를 기본 구성 가능으로 만들지 않으려면 기본 생성자를 선언하지 않는 것이 좋습니다. 그러나 예를 들어, 기본 구성 가능 (예 : X x1; 행의 주석 처리를 제거하려는 경우)하려면 기본 생성자를 선언하고 정의해야합니다.

또한 기본 생성자는 인수없이 호출 할 수있는 생성자뿐 아니라 인수없이 호출 할 수있는 생성자입니다. X::X(int = 5)은 완벽하게 훌륭한 기본 생성자입니다.

0

1) 인수가없는 생성자를 '기본 생성자'라고합니다. 2) 사용자가 다음 생성자를 제공하지 않으면 컴파일러에서 을 기본 생성자로 선언합니다.컴파일러는 다음이이라고되어있는 '기본 생성자'를 선언하는 경우,

4) '암시 적으로 선언 기본 생성자' '암시 적으로 기본 생성자를 선언 한'

2a) Copy Constructor 
    2b) Non-default constructor 
    2C) default constructor. 

3) 두 가지 유형

의입니다 5A) 아니오 참조 변수 5B) 아니오 가상 함수 5C) 없음 가상 기본 클래스가있을 때
4a) **trivial** Constructor 
    4b) **non-trivial** Constructor. 

5) 내재적으로 선언 된 기본 생성자는 '사소한'이라고합니다. 5D) 부모 클래스는 '사소한'생성자,이 도움이

Else, it is said to be 'non-trivial'. 

희망이있다.