프로그램언어/Effective C++

[C++] Effective C++ No.6

에블릿 2009. 3. 16. 16:46

항목 6: 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해 버리자.


예를들어 부동산업자의 업무 지원용으로 관리 프로그램을 생성을 해보도록 하겠습니다.

매물에 대한 가옥이 있을 것입니다. 이것을



요구사항 첫 번째 :

ㅇ 자산은 세상에 하나빡에 없다는 사실, 즉 똑같은게 없다는 의미를 가지며, key값이 된다는 말이겠죠, 또한 사본 즉 복사된 값이 없다는 의미를 가지기도 합니다.




ㅇ 위 코드는 정상적으로 문제가 없는 코드 입니다. 하지만, 의도한 것은 유일무일한 key을 가지고 복사 및 컴파일시 미리 알려주는 행위를 원했습니다.


ㅇ 깝깝해지기 시작합니다. 어떤 클래스에 대한 복사 생성자나 복사 대입 연산자를 선언하지 않으면 컴파일러가 저절로 만들어낼지도 모르기 때문에 그냥 내버려 두면 여러분 클래스는 복사를 지원하게 되는 것이 될겁니다.


ㅇ 컴파일러가 생성하는 함수는 모두 공개된다는, public 맴버가 된다는 사실입니다. 생성자와 복사 대입 연산자가 저절로 만들어지는 것을 막기 위해 여러분이 직접 선언해야 한다는 점은 맞지만, 이것들을 public 맴버로 선언해야 한다고 요구하는 곳은 아무데도 없다는 점을 기억하시기 바랍니다.

ㅇ 이러한 접근에 해당하는 멤버에 대해 private으로 선언해주면 컴파일러는 자신의 기본 버전을 만들 수 없게 됩니다.


private 멤버 함수는 그 클래스의 멤버 함수 및 프렌드( friend) 함수가 호출할 수 있다는 점이 여전히 허점입니다. 이것까지 막으면 그러니까 정의를 안해 버리는 기지를 발휘해 보면 어떨까요? 정의되지 않은 함수를 누군가가 어쩌다가 실수로 호출하려 했다면 분명히 링크 시점에 에러를 보게 될 테니 괸찮습니다.


꼼수의 방법으로 다음과 같이 할 수 있습니다. ( 꼼수는 어디까지나 꼼수 일뿐, 이것을 정규화 하지 말아야 할 방법입니다.)




이러한 방법으로 컴파일에서 다음과 같이 제어 할 수 있습니다.

이와 같은 방법으로 다음과 같은 클래스를 추가하여 사용할 수도 있습니다. 이 항목에 대해서는 뒤 부분에서 점더 자세히 다루어 보도록 하겠습니다.






결과
house.cpp: In copy constructor ‘House::House(const House&)’:
house.cpp:15: error: ‘Uncopy::Uncopy(const Uncopy&)’ is private
house.cpp:21: error: within this context house.cpp: In function ‘int main()’:
house.cpp:38: note: synthesized method ‘House::House(const House&)’ first required here

[ 중요 ] 이것은 잊지 말자

컴파일러에서 자동으로 제공하는 기능을 허용치 않으려면, 대응되는 멤버 함수를 private로 선언한 후에 구현은 하지 않은 채로 두십시요. Uncopy과 비슷한 기본 클래스를 쓰는 것도 한가지 방법입니다.