Membuat objek baru kelas C dengan operator baru () memberikan kesalahan di sini:
class C
{
public:
C() {}
virtual ~C() {}
void operator delete(void*) = delete;
};
int main()
{
C* c = new C;
}
dengan C2280: 'void C::operator delete(void *)': function was explicitly deleted
Tetapi ketika saya mengganti C() {}
dengan C() = default;
atau menghapus baris sehingga kompiler menyisipkan konstruktor default (yang saya percaya memiliki efek yang sama dengan = default
), kode akan dikompilasi dan dijalankan.
Apa perbedaan antara konstruktor default yang dibuat kompiler dan konstruktor default yang ditentukan pengguna yang membuat ini terjadi?
Saya mendapat beberapa petunjuk dalam posting ini , tetapi kelas C di sini (tanpa konstruktor yang disediakan pengguna) tidak sepele karena destruktornya virtual, bukan?
Dikompilasi dengan Visual Studio terbaru, c ++ 17.
c++
delete-operator
default-constructor
yeshjho
sumber
sumber
noexcept
operator delete()
apakah konstruktor ditulis secara manual atau secara implisit dihasilkan. Yang konsisten dengan harapan saya - karena pengecualian dapat dilemparkan olehnew
ekspresi, kompiler perlu mengaksesoperator delete()
.noexcept
akan membuat kompilasi kode, tetapi bagaimana ...?noexcept
seperti yang disebutkan SebastianRedl, maka panggilan untukoperator delete
tidak perlu disertakan. Juga g ++ tidak hanya mengeluh jika destructor itu virtual. Kalau tidak selalu mengkompilasi, bahkan jika konstruktor melempar.Jawaban:
new
Ekspresi memanggil korespondensioperator new
dan kemudian memanggil konstruktor. Jika konstruktor melemparnew
ekspresi pengecualian harus membatalkan efekoperator new
(untuk menghindari kebocoran memori) dengan memanggil yang sesuaioperator delete
. Jika yang terakhir dihapus,new
ekspresi tidak dapat memanggil yang menghasilkan kompilererror: use of deleted function 'static void C::operator delete(void*)'
.Sebuah
noexcept
konstruktor tidak mungkin melempar pengecualian, maka, sesuaioperator delete
tidak perlu karena tidak akan dipanggil olehnew
ekspresi. Sebuahdefault
konstruktor dari kelas sepele juga merupakannoexcept
konstruktor. Kehadiran destruktor virtualoperator delete
harus non-dihapus karena destruktor penghapusan skalar khusus (detail implementasi untuk memungkinkandelete
ekspresi melalui pointer kelas dasar) memanggiloperator delete
.Tampaknya tidak ditentukan oleh standar C ++ apakah kompiler harus diharuskan
operator delete
untuk tidak dihapus bahkan jika itu tidak dapat dipanggil dengannew
ekspresi.gcc
, bagaimanapun, sepertinya tidak menggunakan korespondensioperator delete
dalamnew
ekspresi sama sekali jikadelete
d (memposting laporan bug ).sumber