2016-03-23 33 views
14

Dlaczego mój kompilator MSVC12 nie jest taki?C++ destruktor wywołuje operator delete?

#include <new> 

class thing 
{ 
public: 
    thing() {} 
    ~thing() {} 
    static void operator delete(void* ptr) = delete; 
}; 

int main() 
{ 
    int g; 
    void* p = &g; 
    thing* t1 = new(p) thing(); 
    t1->~thing(); 

    return 0; 
} 

Błąd pojawia się dziwnie na klamry zamykającej main():

błędzie 2 Błąd C2280: 'void rzeczą :: operator delete (void *)': próbuje odwołać usuniętą funkcję

Jeśli skomentuję jawne wywołanie destruktora, błąd zniknie, co oznacza, że ​​jawne wywołanie destruktora próbuje wywołać operację delete (void *). To nie ma intuicyjnego sensu. Jak zapewne widać z tego kodu, już zarządzałem własną pamięcią i nie chcę, aby ktokolwiek kiedykolwiek odwoływał się do usuwania.

+1

To [kompiluje i działa] (http://coliru.stacked-crooked.com/a/b0c0ca91f45c3887) w gcc5, tak jak powinno. Co się stanie, jeśli skompilujesz w trybie zwolnienia? – vsoftco

+1

[cpp.sh/3mqd](http://cpp.sh/3mqd) - gcc działa dobrze –

+0

Wersja wydania ma taki sam błąd. Wydaje się, że jest to błąd kompilatora? – Kumputer

Odpowiedz

5

Jest to z pewnością błąd ponieważ po prostu zastąpienie wywołania wirtualnego destruktorem niewirtualnym: t1->thing::~thing() to działa. Ale oczywiście w tym przypadku nie ma dziedziczenia, a zatem nie ma różnicy między tymi dwiema formami.

Można spróbować i złożyć błąd poprzez the Microsoft Connect site for VS

+0

https://connect.microsoft.com/VisualStudio/Feedback/Details/2511044 – Kumputer

+0

Destruktor nie jest wirtualny –

+0

Nie jest, ale połączenie używające jawnej nazwy metody nazywa się połączeniem niewirtualnym. –