Kiedy / dlaczego miałbym jawnie usunąć mój konstruktor? Zakładając, że powodem jest niedopuszczenie do jego użycia, dlaczego po prostu tego nie zrobić private?
class Foo
{
public:
Foo() = delete;
};
Kiedy / dlaczego miałbym jawnie usunąć mój konstruktor? Zakładając, że powodem jest niedopuszczenie do jego użycia, dlaczego po prostu tego nie zrobić private?
class Foo
{
public:
Foo() = delete;
};
delete. Zarówno pytanie, jak i odpowiedź Luchiana łatwo kwalifikują się jako konstruktywne. Każdy, kto nie oddycha subtelnymi punktami C ++ 11, ale wkrótce będzie musiał wyciągnąć coś z obu.
Odpowiedzi:
Co powiesz na:
//deleted constructor
class Foo
{
public:
Foo() = delete;
public:
static void foo();
};
void Foo::foo()
{
Foo f; //illegal
}
przeciw
//private constructor
class Foo
{
private:
Foo() {}
public:
static void foo();
};
void Foo::foo()
{
Foo f; //legal
}
Zasadniczo są to różne rzeczy. privatemówi ci, że tylko członkowie klasy mogą wywołać tę metodę lub mieć dostęp do tej zmiennej (lub oczywiście przyjaciele). W takim przypadku staticmetoda tej klasy (lub dowolnego innego elementu członkowskiego) może wywołać privatekonstruktor klasy. Nie dotyczy to usuniętych konstruktorów.
Próbka tutaj .
po co jawnie usunąć konstruktora?
Kolejny powód:
używam, deletegdy chcę się upewnić, że klasa jest wywoływana z inicjatorem. Uważam to za bardzo elegancki sposób na osiągnięcie tego bez kontroli w czasie wykonywania.
Kompilator C ++ sprawdza to za Ciebie.
class Foo
{
public:
Foo() = delete;
Foo(int bar) : m_bar(bar) {};
private:
int m_bar;
}
Ten - bardzo uproszczony - kod zapewnia, że nie ma takiej instancji:Foo foo;
Foomiał wiele konstruktorów, ale nie Foo foo;byłby to domyślny, spowodowałoby znacznie dłuższy błąd, wymieniając wszystkie niejawnie zdefiniowane, chronione i prywatne konstruktory, których nie udało się dopasować.
Spotkałem się z domyślnymi kontrolerami zadeklarowanymi jako „usunięte” w kodzie źródłowym LLVM (na przykład w AlignOf.h). Powiązane szablony klas znajdują się zwykle w specjalnej przestrzeni nazw o nazwie „llvm :: detail”. Myślę, że głównym celem było to, że uważali tę klasę tylko za klasę pomocniczą. Nigdy nie zamierzali ich tworzyć; tylko po to, aby używać ich w kontekście innych szablonów klas z pewnymi sztuczkami metaprogramowania, które działają w czasie kompilacji.
Na przykład. istnieje szablon klasy AlignmentCalcImpl, który jest używany tylko w innym szablonie klasy o nazwie AlignOf jako parametr dla operatora sizeof (.). To wyrażenie można ocenić w czasie kompilacji; i nie ma potrzeby tworzenia instancji szablonu -> więc dlaczego nie zadeklarować domyślnego usuwania ctora, aby wyrazić ten zamiar.
Ale to tylko moje przypuszczenie.
= default, nawet klasa nie może z tego korzystać, a ja osobiście wolę zobaczyć użycie usuniętej funkcji. nad Funkcja jest prywatna. Pierwsza z nich wyraźnie stwierdza, że „tego nie należy używać”. Jeśli cokolwiek z tego wyniknie, klasa, która nie jest w stanie tego użyć, ma znaczenie semantyczne.