Game Develop

불필요한 복사생성자, 복사대입연산자 호출을 미리 막아보자. 본문

C++/Effective C++

불필요한 복사생성자, 복사대입연산자 호출을 미리 막아보자.

MaxLevel 2025. 3. 1. 21:57

어떤 객체의 인스턴스한테 유일성을 보장해주고싶을 때가 있다고 가정해보자.

그러면 인스턴스를 만들면 그것과 동일한게 있으면 안되니 복사생성자나 복사대입연산자를 허용하면 안된다.

 

이럴 때 먼저 가장 손쉬운방법은 복사생성자나 복사대입연산자를 private으로 선언해버리는 것이다.

private이니 외부에서 호출할 수 없게 만들어버렸다는 느낌이다.

 

하지만 이 방법은 100% 완벽하지 않다.

왜냐면 클래스의 멤버함수나 프렌드함수에서 해당 복사생성자나 복사대입연산자를 호출해버릴수도 있기 때문이다.

 

멤버함수에서의 호출까지 막을려면 그냥 복사생성자, 복사대입연산자를 '선언'만 하는 것이다.

실제로 이 방법은 C++의 iostream 라이브러리의 몇몇 클래스에서 실제로 적용한 복사방지법이라고 하니, 필요할 때 써먹어도 될 것 같다.

 

다만, 이렇게 할 경우 멤버함수에서의 호출에서는 컴파일시점에서 에러가 뜨는게 아니라 링크단계에서 에러가 뜬다.

에러는 가능한 컴파일시점에서 띄우는게 좋다.

 

아래는 실제 예시

 

 

 

여기보면 main함수에서 HomeForSale클래스의 객체를 만든 후, 복사대입연산자를하면 컴파일에러를 띄워준다.

왜냐면 복사대입연산자가 private으로 되어있으니 접근할 수 없기 때문이다.

 

그러나 HomeForSale 멤버함수인 Test 내에서는 컴파일에러가 뜨지 않았다.

대신 컴파일할 경우, 정의가 되어있지 않기때문에 링크에러가 뜬다.

 

 

대충 이렇게...

 

 

 

그러나 모름지기 에러는 컴파일전에 에러를 띄우는게 가장 베스트이다.

그러기 위해 복사방지용 클래스를 만들어서 상속시키는 방법이 있다.

 

 

이렇게 Uncopyable이라는 복사방지용 클래스를 하나 만들어주고, 이거를 복사방지하려는 클래스에 private으로 상속시키면 된다.

그러면 클래스 멤버함수에서도 컴파일에러를 미리 띄울 수 있는것을 확인할 수 있다.

 

위와같은 방법들처럼, 컴파일러가 자동으로 제공하는 기능을 사용하지않으려면 일부러 선언만 하고 정의를 안하는식으로해서 우회할 수 있다.