생성자를 언제 / 왜 명시 적으로 삭제해야합니까? 그 이유가 사용을 막기 위함이라고 가정하면, 왜 그렇게하지 private않습니까?
class Foo
{
public:
Foo() = delete;
};
생성자를 언제 / 왜 명시 적으로 삭제해야합니까? 그 이유가 사용을 막기 위함이라고 가정하면, 왜 그렇게하지 private않습니까?
class Foo
{
public:
Foo() = delete;
};
delete. 질문과 Luchian의 대답 모두 쉽게 건설적인 것으로 간주됩니다. C ++ 11의 미세한 요점을 숨겨주지 않는 사람은 곧 두 가지 모두에서 무언가를 얻을 수 있습니다.
답변:
어때 :
//deleted constructor
class Foo
{
public:
Foo() = delete;
public:
static void foo();
};
void Foo::foo()
{
Foo f; //illegal
}
대
//private constructor
class Foo
{
private:
Foo() {}
public:
static void foo();
};
void Foo::foo()
{
Foo f; //legal
}
그들은 기본적으로 다른 것들입니다. private클래스의 멤버 만 해당 메서드를 호출하거나 해당 변수 (또는 친구)에 액세스 할 수 있음을 알려줍니다. 이 경우 static해당 클래스 (또는 다른 멤버) 의 메서드가 클래스 private생성자 를 호출하는 것은 합법적입니다 . 삭제 된 생성자에는 적용되지 않습니다.
생성자를 명시 적으로 삭제하는 이유는 무엇입니까?
또 다른 이유 : 이니셜 라이저로 클래스를 호출하고 싶을 때
사용 delete합니다. 런타임 검사없이 이것을 달성하는 매우 우아한 방법이라고 생각합니다.
C ++ 컴파일러가이 검사를 수행합니다.
class Foo
{
public:
Foo() = delete;
Foo(int bar) : m_bar(bar) {};
private:
int m_bar;
}
매우 단순화 된 이 코드는 다음과 같은 인스턴스화가 없음을 보장합니다.Foo foo;
Foo기본 생성자가 아닌 생성자가 여러 개있는 경우 Foo foo;일치하지 못한 모든 암시 적으로 정의되고 보호되는 개인 생성자를 나열하는 훨씬 더 긴 오류가 발생합니다.
LLVM의 소스 코드 (예 : AlignOf.h)에서 '삭제됨'으로 선언 된 기본 ctor를 만났습니다. 연결된 클래스 템플릿은 일반적으로 'llvm :: detail'이라는 특수 네임 스페이스에 있습니다. 내가 생각하는 모든 목적은 그들이 그 클래스를 도우미 클래스로만 생각했기 때문이라고 생각합니다. 그들은 그들을 인스턴스화 할 의도가 없었습니다. 컴파일 타임에 실행되는 메타 프로그래밍 트릭이있는 다른 클래스 템플릿의 컨텍스트 내에서만 사용합니다.
예 : 이 AlignmentCalcImpl 클래스 템플릿은 sizeof (.) 연산자의 매개 변수로 AlignOf라는 다른 클래스 템플릿 내에서만 사용됩니다. 이 표현식은 컴파일 타임에 평가 될 수 있습니다. 그리고 템플릿을 인스턴스화 할 필요가 없습니다. 그래서이 의도를 표현하기 위해 기본 ctor delete를 선언하는 것은 어떻습니까?
그러나 그것은 나의 가정 일뿐입니다.
= default,조차 클래스를 사용할 수 있으며, 개인적으로보고 선호 삭제 기능을 사용. over Function은 비공개입니다. 전자는 "이것은 사용하기위한 것이 아닙니다."라고 명시 적으로 말합니다. 그것에서 나오는 것이 있다면, 그것을 사용할 수없는 클래스는 실제로 의미 상 차이를 만듭니다.