티스토리 뷰

728x90

 

컴파일러가 자동으로 생성하는 함수를 불필요할 때 명시적으로 금지하자

클래스를 사용할 때, 때로는 복사 생성자복사 대입 연산자의 사용을 금지하고 싶을 때가 있습니다. 그렇다고 해서 우리가 이를 구현하지 않았다고 해서 자동으로 금지되는 것이 아니라, 컴파일러가 자동으로 생성해버립니다. 이를 방지하는 방법은 명확히 복사 생성자복사 대입 연산자의 사용을 금지하는 것입니다.

문제 상황


class CA
{
    // 아무 것도 구현하지 않음
};

int main()
{
    CA ca;
    CA ca2;
    CA ca3(ca); // 복사 생성자 호출
    ca2 = ca;   // 복사 대입 연산자 호출
}

위의 예제에서 CA 클래스는 복사 생성자복사 대입 연산자가 명시적으로 정의되지 않았습니다. 그럼에도 불구하고, 컴파일러는 이를 자동으로 생성하여 사용합니다.


해결 방법: 자동 생성된 복사 생성자와 복사 대입 연산자 금지

복사 생성자와 복사 대입 연산자의 자동 생성을 방지하기 위해, 이 두 함수를 private로 선언합니다. 이를 통해, 컴파일러가 이 함수들을 생성하려 해도 접근할 수 없게 되어, 객체의 복사와 대입을 금지할 수 있습니다.

예제 1


class CA
{
private:
    CA(const CA&);               // 복사 생성자
    CA& operator=(const CA&);    // 복사 대입 연산자
};

이렇게 하면 컴파일러는 복사 생성자와 복사 대입 연산자를 자동으로 생성할 수 없게 됩니다. 이 코드에서는 복사나 대입을 시도할 경우 컴파일 에러가 발생하게 됩니다.

하지만, private로 선언했을 때 멤버 함수는 여전히 접근 가능한 문제가 있습니다. 이 문제를 해결하려면, 복사 생성자와 복사 대입 연산자를 선언만 하고 정의하지 않으면 됩니다.


복사 금지 클래스 상속 사용하기

또 다른 해결책은 복사와 대입을 방지하는 기본 클래스를 설계하고, 복사를 방지하고 싶은 클래스들이 이를 상속받게 하는 것입니다. 이를 통해 복사 방지의 의도를 명확히 할 수 있습니다.

예제 2


class UnCopy
{
protected:
    UnCopy() {}    // 파생 클래스에서 생성 가능
    ~UnCopy() {}   // 소멸자

private:
    UnCopy(const UnCopy&);               // 복사 생성자
    UnCopy& operator=(const UnCopy&);    // 복사 대입 연산자
};

class CA : public UnCopy
{
    // 추가 멤버와 함수
};

위 코드에서, UnCopy 클래스는 복사 금지를 위한 클래스입니다. CA 클래스는 이를 상속받음으로써 복사와 대입이 금지됩니다. 이처럼 복사를 방지하는 클래스를 별도의 기본 클래스로 두고, 이를 상속받도록 하여 코드를 깔끔하게 관리할 수 있습니다.


결론

컴파일러가 자동으로 제공하는 복사 생성자복사 대입 연산자를 허용하지 않으려면, 해당 멤버 함수를 private로 선언하고 정의하지 않거나, 이를 방지하는 기본 클래스를 설계하여 상속받도록 합니다. 이로써 불필요한 복사와 대입을 명시적으로 차단할 수 있습니다.

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함
250x250