Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
"deklaracja": próba odwołania się do usuniętej funkcji
Kompilator wykrył próbę deleted
odwołania do funkcji. Ten błąd może być spowodowany wywołaniem funkcji składowej, która została jawnie oznaczona jako = deleted
w kodzie źródłowym. Ten błąd może być również spowodowany wywołaniem niejawnej funkcji specjalnej składowej struktury lub klasy, która jest automatycznie zadeklarowana i oznaczona przez deleted
kompilator. Aby uzyskać więcej informacji o tym, kiedy kompilator automatycznie generuje default
lub deleted
specjalne funkcje członkowskie, zobacz Specjalne funkcje składowe.
Przykład: jawnie usunięte funkcje
Wywołanie jawnej deleted
funkcji powoduje ten błąd. deleted
Jawna funkcja składowa oznacza, że klasa lub struktura jest celowo zaprojektowana, aby zapobiec jego użyciu, więc aby rozwiązać ten problem, należy zmienić kod, aby go uniknąć.
// C2280_explicit.cpp
// compile with: cl /c /W4 C2280_explicit.cpp
struct A {
A();
A(int) = delete;
};
struct B {
A a1;
A a2 = A(3); // C2280, calls deleted A::A(int)
// To fix, remove the call to A(int)
};
void f() {
B b; // calls implicit B::B(void)
}
Przykład: niezainicjowane elementy członkowskie danych
Niezainicjowany element członkowski lub const
element członkowski danych typu referencyjnego powoduje, że kompilator niejawnie zadeklarował deleted
konstruktor domyślny. Aby rozwiązać ten problem, zainicjuj element członkowski danych po zadeklarowaniu.
// C2280_uninit.cpp
// compile with: cl /c C2280_uninit.cpp
struct A {
const int i; // uninitialized const-qualified data
// members or reference type data members cause
// the implicit default constructor to be deleted.
// To fix, initialize the value in the declaration:
// const int i = 42;
} a; // C2280
Przykład: odwołania i składowe danych const
Element const
członkowski danych typu lub odwołania powoduje, że kompilator deklaruje operator przypisania kopiowania deleted
. Po zainicjowaniu tych elementów członkowskich nie można przypisać do niego, więc prosta kopia lub przenoszenie nie może działać. Aby rozwiązać ten problem, zalecamy zmianę logiki w celu usunięcia operacji przypisania, które powodują błąd.
// C2280_ref.cpp
// compile with: cl /c C2280_ref.cpp
extern int k;
struct A {
A();
int& ri = k; // a const or reference data member causes
// implicit copy assignment operator to be deleted.
};
void f() {
A a1, a2;
// To fix, consider removing this assignment.
a2 = a1; // C2280
}
Przykład: wymienne usuwanie niejawnej kopii
Jeśli klasa deklaruje konstruktor przenoszenia lub operator przypisania przenoszenia, ale nie deklaruje jawnie konstruktora kopiowania, kompilator niejawnie deklaruje konstruktor kopiujący i definiuje go jako deleted
. Podobnie, jeśli klasa deklaruje konstruktor przenoszenia lub operator przypisania przenoszenia, ale nie deklaruje jawnie operatora przypisania kopiowania, kompilator niejawnie deklaruje operator przypisania kopiowania i definiuje go jako deleted
. Aby rozwiązać ten problem, należy jawnie zadeklarować te elementy członkowskie.
Po wyświetleniu błędu C2280 w połączeniu z elementem unique_ptr
, jest prawie na pewno, ponieważ próbujesz wywołać jego konstruktor kopiowania, który jest funkcją deleted
. Zgodnie z projektem unique_ptr
nie można skopiować elementu . Zamiast tego użyj konstruktora przenoszenia, aby przenieść własność.
// C2280_move.cpp
// compile with: cl /c C2280_move.cpp
class base
{
public:
base();
~base();
base(base&&);
// Move constructor causes copy constructor to be
// implicitly declared as deleted. To fix this
// issue, you can explicitly declare a copy constructor:
// base(base&);
// If you want the compiler default version, do this:
// base(base&) = default;
};
void copy(base *p)
{
base b{*p}; // C2280
}
Przykład: wariant i elementy nietrwałe
Wersje kompilatora przed programem Visual Studio 2015 Update 2 były niezgodne i wygenerowały konstruktory domyślne i destruktory dla anonimowych związków. Są one teraz niejawnie zadeklarowane jako deleted
. Te wersje zezwalały również na niezgodną niejawną definicję default
konstruktorów kopiowania i przenoszenia oraz default
operatorów przypisania kopiowania i przenoszenia w klasach i strukturach, które mają volatile
zmienne składowe. Kompilator rozważa teraz, że mają nietrywialne konstruktory i operatory przypisania i nie generują default
implementacji. Gdy taka klasa jest elementem członkowskim unii lub anonimowego związku wewnątrz klasy, konstruktory kopii i przenoszenia oraz operatory przypisania kopiowania i przenoszenia unii lub klasy są niejawnie zdefiniowane jako deleted
. Aby rozwiązać ten problem, należy jawnie zadeklarować wymagane specjalne funkcje członkowskie.
// C2280_variant.cpp
// compile with: cl /c C2280_variant.cpp
struct A {
A() = default;
A(const A&);
};
struct B {
union {
A a;
int i;
};
// To fix this issue, declare the required
// special member functions:
// B();
// B(const B& b);
};
int main() {
B b1;
B b2(b1); // C2280
}
Przykład: usunięte pośrednie składowe podstawowe
Wersje kompilatora przed programem Visual Studio 2015 Update 2 były niezgodne i zezwalały klasy pochodnej na wywoływanie specjalnych funkcji składowych pośrednio pochodnych private virtual
klas bazowych. Kompilator wydaje teraz błąd kompilatora C2280, gdy takie wywołanie jest wykonywane.
W tym przykładzie klasa top
pośrednio pochodzi z prywatnej wirtualnej maszyny wirtualnej base
. W kodzie zgodnym sprawia to, że elementy członkowskie są base
niedostępne top
; obiekt typu top
nie może być domyślnie skonstruowany ani zniszczony. Aby rozwiązać ten problem w kodzie, który polegał na starym zachowaniu kompilatora, zmień klasę pośrednią, aby używać protected virtual
wyprowadzania, lub zmień klasę top
tak, aby korzystała z wyprowadzania bezpośredniego:
// C2280_indirect.cpp
// compile with: cl /c C2280_indirect.cpp
class base
{
protected:
base();
~base();
};
class middle : private virtual base {};
// Possible fix: Replace line above with:
// class middle : protected virtual base {};
class top : public virtual middle {}; // C4594, C4624
// Another possible fix: use direct derivation:
// class top : public virtual middle, private virtual base {};
void destroy(top *p)
{
delete p; // C2280
}