2008. 8. 26. 00:16

동적으로 할당되는 메모리를 갖는 클래스를 위해서는 복사 생성자와 치환 연산자를 선언하라

클래스 내에 포인터가 있는 경우 자신만의 복사 생성자와 치환 연산자를 작성하는 것이다.

* 이 함수들 안에서, 포인터에 의해 가리켜지고 있는 데이터 구조를 복사해서 객체마다 자신만의 복사본을 갖게 하거나,

* 일종의 참조 계수(reference counting) 방식을 사용해서 특정 데이터 구조가 얼마나 포인트되고 있는지 계속적으로 유지하는 방법이 있을 수 있다.

참조 계수 방법은 좀더 복잡하고, 생성자와 소멸자에서 더 많은 처리를 해야 하지만(전부는 아니더라도), 대부분의 응용 프로그램에서 많은 메모리 사용량 감소와 속도 향상을 가져올 수 있다.

어떤 클래스들에 대해서는, 복사 생성자나 치환 연산자를 만들지 않는 것이 만드는 경우보다 나을 수 있다.
이런 경우 함수들을 private으로 선언하기만 하면 될 것이다. 이렇게 하면, 클래스의 사용자가 호출하는 것을 막을 수도 있고, 컴파일러가 기본 함수들을 발생시키는 것도 막을 수 있다.

class String {

public:

           String (const char * value = 0);

           ~String();

private:

           char * data;

}

 

String::String(const char * value)

{

           if( value ) {

                     data = new char[ strlen( value ) + 1 ];

                     strcpy( data, value );

           }

           else {

                     data = new char[1];

                     *data = 0;

           }

}

 

inline String::~String() { delete [] data; }


생성자의 코드에서 new를 호출할 때, 하나의 객체를 만드는 경우에도 []를 사용하는 주의를 기울였다. new와 delete 에는 동일한 형식을 사용하는 것이 매우 중요하므로, new에 대한 코드를 작성할 때 []를 사용한 것이다. 이 점은 반드시 잊지 말아야 한다. 항상 해당하는 new에 []를 사용한 경우에만 delete에도 []를 사용해야 한다.

참고 : Effective C++, Scott Meyers 저