C++11에서 도입된 = delete 키워드는 특정 함수(연산자 포함)의 사용을 금지하고,
컴파일 단계에서 에러를 발생시켜 불필요한 호출을 차단하는 기능을 제공합니다.
✅ = delete가 필요한 이유
✅ 이전 방식과 비교 (private 접근 제어와 friend 문제점)
✅ 실제 사용 예제 및 코드 분석
이 문서에서는 = delete의 필요성과 사용법을 예제 코드와 함께 상세히 분석하겠습니다.
Knightclass Knight
{
public:
void operator=(const Knight& k) = delete;
✅ 복사 대입 연산자 삭제
operator= 연산자를 삭제된 함수 (= delete) 로 선언하여 복사 대입 연산을 금지. = delete는 해당 함수 호출을 컴파일러 수준에서 차단하므로,private 접근 제어)보다 명확하고 안전한 방법. // 예전 문법
private:
// 정의되지 않은 비공개(private) 함수
void operator=(const Knight& k);
✅ C++11 이전에는 private으로 복사 대입을 차단
operator=를 private으로 선언하면 외부에서 직접 호출 불가능. friend 접근)class Admin
{
public:
void CopyKnight(const Knight& k)
{
Knight k1;
// k1 = k; // friend 키워드를 사용하면 private 복사도 가능
// delete 사용을 권장
✅ friend를 사용하면 private 복사 대입도 호출 가능
✅ C++11 이전 방식의 취약점
private으로 선언했지만, friend 클래스를 통해 접근하면 차단이 무력화됨. = delete를 사용하면 이런 문제를 컴파일러 수준에서 완전히 차단 가능. // k1 = k; // 에러 발생 (컴파일 단계에서 차단됨)
}
};
✅ k1 = k;는 operator=가 = delete이므로 컴파일 에러 발생
= delete를 사용하면 컴파일러가 조기에 문제를 발견.main() 함수 분석int main()
{
Knight k1;
Knight k2;
// k1 = k2; // 안됨 (컴파일 에러 발생)
✅ 복사 대입 연산 (k1 = k2;) 금지됨
operator=가 삭제되었으므로 컴파일러가 즉시 에러 발생. Admin admin;
// admin.CopyKnight(k1); // 컴파일 에러 발생
✅ Admin::CopyKnight() 내부에서 operator=를 호출하므로 에러 발생
= delete를 사용하면 잘못된 코드가 실행되지 않도록 차단 가능. = delete vs 기존 방식 비교| 기능 | 기존 방식 (private) | = delete |
|---|---|---|
| 복사 대입 차단 | private으로 제한하지만 완벽하지 않음 | 완전히 차단 (컴파일 에러) |
| friend 문제 | friend 클래스를 사용하면 우회 가능 | friend 사용 여부와 관계없이 차단 |
| 링크 에러 | 조기에 발견 어려움 (링크 단계에서 에러) | 컴파일 단계에서 즉시 발견 |
| 사용법 | private에 선언하고 구현부 제거 | = delete 한 줄이면 끝! |
| 가독성 | 명확하지 않음 | = delete로 의도가 명확 |
✅ C++11 이후에는 = delete 사용을 권장!
✅ 컴파일 단계에서 즉시 차단하여 조기에 오류 발견 가능!
= delete의 활용 예제Singleton 패턴)class Singleton
{
public:
static Singleton& GetInstance()
{
static Singleton instance;
return instance;
}
Singleton(const Singleton&) = delete;
void operator=(const Singleton&) = delete;
private:
Singleton() {} // 기본 생성자 `private`
};
✅ Singleton 패턴에서 복사/대입을 금지하여 객체 중복 생성 방지
✅ = delete를 사용하면 컴파일 단계에서 실수로 복사하는 문제를 완벽히 차단
class NonInstantiable
{
private:
NonInstantiable() = delete; // 기본 생성자를 삭제하여 객체 생성 차단
};
✅ 객체 생성이 필요 없는 클래스를 만들 때 활용
✅ 예제: static 함수만 존재하는 유틸리티 클래스
class Example
{
public:
Example(int x) {}
Example(double) = delete; // `double`을 `int`로 변환하는 것을 금지
};
int main()
{
Example e1(10); // OK
// Example e2(3.14); // 컴파일 에러 발생
}
✅ 특정 타입 변환을 명확히 차단
✅ 잘못된 타입 사용을 방지하여 코드 안정성을 높임