티스토리 뷰


Class Empty { } ;

동일함

Class Empty
{
   
Public:

             Empty() { . . . }                                                          // 기본 생성자

             Empty ( const Empty & rhs ) { . . . }                     // 복사 생성자

             ~Empty ( ) { . . . }                                                     // 소멸자

 

             Empty & operator = ( const Empty & rhs ) { . . . }           // 복사 대입 연산자

};


○ 이유

C++의 함수 중에서 프로그래머가 선언해주지 않아도 컴파일러가 저절로 선언해주는 멤버함수가 있다.

복사생성자, 복사 대입연산자, 소멸자가 있는데, 컴파일러가 만들어주는 함수는 모두 기본으로 만들어준다.

 

컴파일러가 선언하는 함수는 모두 public 멤버이며 inline 함수이다

자동 생성된 복사 생성자는 각 멤버에 대해, 대응되는 자료를 각각 그 멤버의 복사생성자를 이용하여 생성시킨다.

 

template< typename T >

class NamedObject {

public:

NamedObject( const char* name, const T& value );   // 기본생성자가 없어도 사용자가 직접 정의한 생성자가 있다면

    NamedObject( const std::string& name, const T& value );   // 따로 기본생성자를 자동생성해주지 않는다.

    . . . .                                                    // 생성자가 하나도 없을때만 기본생성자가 자동 생성된다. 

private:

    std::string nameValue;

    T objectValue;

};

NamedObject<int> no1( "Smallest Prime Number", 2 );

NamedObject<int> no2( no1 );      // 여기서 자동 생성된 복사 생성자를 호출한다

NamedObject의 각 멤버인 nameValue와

objectValue의 복사생성자를 호출한다.

                                   // 예) no2.nameValue( no1.nameValue );

                                   // 그러나 objectValue의 경우 기본제공 타입인 int형이므로, 단지 각 비트를 그대로 복사한다.


 자동 생성된 복사 대입 연산자 역시 비슷한 원리로 작동한다. 

그런데 모든 경우에 자동 생성되지는 않는다. 

규칙에 맞아야 하는데, 이를테면 멤버 중에 참조자나 상수가 있다면, 컴파일러는 복사 대입 연산자를 생성시키지 못하고, 컴파일 에러를 낸다. 참조자는 참조 대상을 바꿀 수 없고, 상수는 변경이 불가능하기 때문이다.


복사 대입 연산자를 private로 선언한 클래스에서 파생된 클래스는 자동적으로 복사 대입 연산자가 생성되지 않는다.


○ 결론

컴파일러는 경우에 따라 클래스에 대해 기본 생성자, 복사 생성자, 복사 대입 연산자, 소멸자를 암시적으로 만들어 놓을 수 있습니다.

객체 내부의 멤버가 새로 생긴 경우, 생성자, 대입연산자, 소멸자를 새로 갱신해주어야한다

클래스내의 변수중에 참조자나 상수형 변수가 있을 경우, 클래스에서 복사 대입연산자나 복사생성자가 호출될 때 컴파일러는 에러를 발생시킨다. 왜냐하면, c++의 참조자는 원래 자신이 참조하고 있는 것과 다른 객체를 참조 할수 없기 때문이다. 따라서 이러한 문제점을 해결하기 위해서는 사용자가 직접 복사생성자나, 대입연산자의 정의 해주어야 한다

 

댓글
댓글쓰기 폼