new
operator (C++)
Mencoba mengalokasikan dan menginisialisasi objek atau array objek dari jenis tempat penampung atau tertentu, dan mengembalikan pointer nonzero yang diketik dan cocok ke objek (atau ke objek awal array).
Sintaks
new-expression
:
::
optnew
new-placement
optnew-type-id
new-initializer
opt
::
optnew
new-placement
opt(
type-id
)
new-initializer
opt
new-placement
:
(
expression-list
)
new-type-id
:
type-specifier-seq
new-declarator
opt
new-declarator
:
ptr-operator
new-declarator
opt
noptr-new-declarator
noptr-new-declarator
:
[
expression
]
attribute-specifier-seq
opt
noptr-new-declarator
[
constant-expression
]
attribute-specifier-seq
opt
new-initializer
:
(
expression-list
opt)
braced-init-list
Keterangan
Jika tidak berhasil, new
mengembalikan nol atau melempar pengecualian. Untuk informasi selengkapnya, lihat Operator new
dan delete
. Anda dapat mengubah perilaku default ini dengan menulis rutinitas penanganan pengecualian kustom dan memanggil _set_new_handler
fungsi pustaka run-time dengan nama fungsi Anda sebagai argumennya.
Untuk informasi tentang cara membuat objek pada tumpukan terkelola di C++/CLI dan C++/CX, lihat gcnew.
Catatan
Ekstensi Komponen Microsoft C++ (C++/CX) menyediakan dukungan untuk kata kunci untuk new
menambahkan entri slot yang dapat vtable. Untuk informasi selengkapnya, lihat new
(slot baru di vtable)
Ketika new
digunakan untuk mengalokasikan memori untuk objek kelas C++, konstruktor objek dipanggil setelah memori dialokasikan.
delete
Gunakan operator untuk membatalkan alokasi memori yang dialokasikan oleh new
operator. delete[]
Gunakan operator untuk menghapus array yang dialokasikan oleh new
operator.
Contoh berikut mengalokasikan lalu membebaskan array dua dimensi karakter berukuran dim
10. Saat mengalokasikan array multidemikasi, semua dimensi kecuali yang pertama harus berupa ekspresi konstanta yang mengevaluasi ke nilai positif. Dimensi array paling kiri dapat berupa ekspresi apa pun yang mengevaluasi ke nilai positif. Saat mengalokasikan array menggunakan new
operator, dimensi pertama bisa nol; new
operator mengembalikan pointer unik.
char (*pchar)[10] = new char[dim][10];
delete [] pchar;
type-id
tidak boleh berisi const
, volatile
, deklarasi kelas, atau deklarasi enumerasi. Ekspresi berikut ini berbentuk tidak baik:
volatile char *vch = new volatile char[20];
Operator new
tidak mengalokasikan jenis referensi karena bukan objek.
Operator new
tidak dapat digunakan untuk mengalokasikan fungsi, tetapi dapat digunakan untuk mengalokasikan pointer ke fungsi. Contoh berikut mengalokasikan lalu membebaskan array tujuh pointer ke fungsi yang mengembalikan bilangan bulat.
int (**p) () = new (int (*[7]) ());
delete p;
Jika Anda menggunakan operator new
tanpa argumen tambahan, dan mengkompilasi dengan /GX
opsi , , /EHa
atau /EHs
, pengkompilasi menghasilkan kode untuk memanggil operator delete
jika konstruktor melempar pengecualian.
Daftar berikut menjelaskan elemen tata bahasa dari new
:
new-placement
Menyediakan cara meneruskan argumen tambahan jika Anda kelebihan beban new
.
type-id
Menentukan jenis yang akan dialokasikan; dapat berupa jenis bawaan atau yang ditentukan pengguna. Jika spesifikasi jenis rumit, spesifikasi dapat dikelilingi oleh tanda kurung untuk memaksa urutan pengikatan. Jenisnya mungkin tempat penampung (auto
) yang jenisnya ditentukan oleh pengkompilasi.
new-initializer
Menyediakan nilai untuk objek yang diinisialisasi. Inisialisasi tidak dapat ditentukan untuk array. Operator new
akan membuat array objek hanya jika kelas memiliki konstruktor default.
noptr-new-declarator
Menentukan batas array. Saat mengalokasikan array multidemikasi, semua dimensi kecuali yang pertama harus berupa ekspresi konstanta yang mengevaluasi ke nilai positif yang dapat dikonversi ke std::size_t
. Dimensi array paling kiri dapat berupa ekspresi apa pun yang mengevaluasi ke nilai positif. Berlaku attribute-specifier-seq
untuk jenis array terkait.
Contoh: Mengalokasikan dan membebaskan array karakter
Contoh kode berikut mengalokasikan array karakter dan objek kelas CName
lalu membebaskannya.
// expre_new_Operator.cpp
// compile with: /EHsc
#include <string.h>
class CName {
public:
enum {
sizeOfBuffer = 256
};
char m_szFirst[sizeOfBuffer];
char m_szLast[sizeOfBuffer];
public:
void SetName(char* pszFirst, char* pszLast) {
strcpy_s(m_szFirst, sizeOfBuffer, pszFirst);
strcpy_s(m_szLast, sizeOfBuffer, pszLast);
}
};
int main() {
// Allocate memory for the array
char* pCharArray = new char[CName::sizeOfBuffer];
strcpy_s(pCharArray, CName::sizeOfBuffer, "Array of characters");
// Deallocate memory for the array
delete [] pCharArray;
pCharArray = NULL;
// Allocate memory for the object
CName* pName = new CName;
pName->SetName("Firstname", "Lastname");
// Deallocate memory for the object
delete pName;
pName = NULL;
}
Contoh: new
operator
Jika Anda menggunakan bentuk new
penempatan operator (formulir dengan lebih banyak argumen daripada ukuran), pengkompilasi tidak mendukung bentuk delete
penempatan operator jika konstruktor melempar pengecualian. Contohnya:
// expre_new_Operator2.cpp
// C2660 expected
class A {
public:
A(int) { throw "Fail!"; }
};
void F(void) {
try {
// heap memory pointed to by pa1 will be deallocated
// by calling ::operator delete(void*).
A* pa1 = new A(10);
} catch (...) {
}
try {
// This will call ::operator new(size_t, char*, int).
// When A::A(int) does a throw, we should call
// ::operator delete(void*, char*, int) to deallocate
// the memory pointed to by pa2. Since
// ::operator delete(void*, char*, int) has not been implemented,
// memory will be leaked when the deallocation can't occur.
A* pa2 = new(__FILE__, __LINE__) A(20);
} catch (...) {
}
}
int main() {
A a;
}
Menginisialisasi objek yang dialokasikan dengan new
Bidang opsional new-initializer
disertakan dalam tata bahasa untuk new
operator. Bidang ini memungkinkan objek baru diinisialisasi dengan konstruktor yang ditentukan pengguna. Untuk informasi selengkapnya tentang cara inisialisasi dilakukan, lihat Inisialisasi. Contoh berikut mengilustrasikan cara menggunakan ekspresi inisialisasi dengan new
operator:
// expre_Initializing_Objects_Allocated_with_new.cpp
class Acct
{
public:
// Define default constructor and a constructor that accepts
// an initial balance.
Acct() { balance = 0.0; }
Acct( double init_balance ) { balance = init_balance; }
private:
double balance;
};
int main()
{
Acct *CheckingAcct = new Acct;
Acct *SavingsAcct = new Acct ( 34.98 );
double *HowMuch = new double { 43.0 };
// ...
}
Dalam contoh ini, objek CheckingAcct
dialokasikan menggunakan new
operator, tetapi tidak ada inisialisasi default yang ditentukan. Jadi, konstruktor default untuk kelas , Acct()
, dipanggil. Kemudian objek SavingsAcct
dialokasikan dengan cara yang sama, kecuali bahwa objek secara eksplisit diinisialisasi menjadi 34,98. Karena 34,98 berjenis double
, konstruktor yang mengambil argumen dari jenis tersebut dipanggil untuk menangani inisialisasi. Terakhir, jenis HowMuch
non-kelas diinisialisasi menjadi 43.0.
Jika objek adalah jenis kelas dan kelas tersebut memiliki konstruktor (seperti dalam contoh sebelumnya), objek dapat diinisialisasi oleh new
operator hanya jika salah satu kondisi ini terpenuhi:
Argumen yang disediakan dalam penginisialisasi cocok dengan argumen konstruktor.
Kelas memiliki konstruktor default (konstruktor yang dapat dipanggil tanpa argumen).
Inisialisasi eksplisit per elemen tidak dapat dilakukan saat mengalokasikan array menggunakan new
operator; hanya konstruktor default, jika ada, yang dipanggil. Untuk informasi selengkapnya, lihat Argumen default.
Jika alokasi memori gagal (operator new
mengembalikan nilai 0), tidak ada inisialisasi yang dilakukan. Perilaku ini melindungi dari upaya untuk menginisialisasi data yang tidak ada.
Seperti halnya panggilan fungsi, urutan di mana ekspresi yang diinisialisasi dievaluasi tidak ditentukan. Selain itu, Anda tidak boleh mengandalkan ekspresi ini dievaluasi sepenuhnya sebelum alokasi memori berlangsung. Jika alokasi memori gagal dan new
operator mengembalikan nol, beberapa ekspresi dalam penginisialisasi mungkin tidak dievaluasi sepenuhnya.
Masa pakai objek yang dialokasikan dengan new
Objek yang dialokasikan dengan new
operator tidak dihancurkan saat cakupan di mana objek ditentukan keluar. new
Karena operator mengembalikan penunjuk ke objek yang dialokasikannya, program harus menentukan penunjuk dengan cakupan yang sesuai untuk mengakses dan menghapus objek tersebut. Contohnya:
// expre_Lifetime_of_Objects_Allocated_with_new.cpp
// C2541 expected
int main()
{
// Use new operator to allocate an array of 20 characters.
char *AnArray = new char[20];
for( int i = 0; i < 20; ++i )
{
// On the first iteration of the loop, allocate
// another array of 20 characters.
if( i == 0 )
{
char *AnotherArray = new char[20];
}
}
delete [] AnotherArray; // Error: pointer out of scope.
delete [] AnArray; // OK: pointer still in scope.
}
Setelah pointer AnotherArray
keluar dari cakupan dalam contoh, objek tidak dapat lagi dihapus.
Cara new
kerja
new-expression
(ekspresi yang berisi new
operator) melakukan tiga hal:
Menemukan dan mencadangkan penyimpanan untuk objek atau objek yang akan dialokasikan. Ketika tahap ini selesai, jumlah penyimpanan yang benar dialokasikan, tetapi belum menjadi objek.
Menginisialisasi objek. Setelah inisialisasi selesai, informasi yang cukup ada untuk penyimpanan yang dialokasikan menjadi objek.
Mengembalikan penunjuk ke objek dari jenis penunjuk yang berasal dari
new-type-id
atautype-id
. Program ini menggunakan penunjuk ini untuk mengakses objek yang baru dialokasikan.
Operator new
memanggil fungsi operator new
. Untuk array dari jenis apa pun, dan untuk objek yang bukan class
, , struct
atau union
jenis, fungsi global, ::operator new
, dipanggil untuk mengalokasikan penyimpanan. Objek jenis kelas dapat menentukan fungsi anggota statis mereka sendiri operator new
berdasarkan per kelas.
Ketika pengkompilasi menemukan new
operator untuk mengalokasikan objek jenis T
, ia mengeluarkan panggilan ke T::operator new( sizeof(T) )
atau, jika tidak ada yang ditentukan operator new
pengguna yang ditentukan, ::operator new( sizeof(T) )
. Ini adalah bagaimana new
operator dapat mengalokasikan jumlah memori yang benar untuk objek.
Catatan
Argumen ke operator new
berjenis std::size_t
. Jenis ini didefinisikan dalam direct.h>, <malloc.h>, <memory.h>, <search.h>, <stddef.h>, <stdio.h>, <stdlib.h>, <string.h>, dan <time.h><.
Opsi dalam tata bahasa memungkinkan spesifikasi new-placement
(lihat Tata Bahasa untuk new
Operator). Parameter new-placement
hanya dapat digunakan untuk implementasi operator new
yang ditentukan pengguna ; ini memungkinkan informasi tambahan untuk diteruskan ke operator new
. Ekspresi dengan bidang seperti T *TObject = new ( 0x0040 ) T;
diterjemahkan ke T *TObject = T::operator new( sizeof( T ), 0x0040 );
jika kelas T memiliki anggota operator new
, jika tidak ke T *TObject = ::operator new( sizeof( T ), 0x0040 );
.new-placement
Niat new-placement
asli bidang ini adalah untuk memungkinkan objek yang bergantung pada perangkat keras dialokasikan pada alamat yang ditentukan pengguna.
Catatan
Meskipun contoh sebelumnya hanya menunjukkan satu argumen di new-placement
bidang , tidak ada batasan tentang berapa banyak argumen tambahan yang dapat diteruskan ke operator new
cara ini.
Bahkan ketika operator new
telah didefinisikan untuk jenis T
kelas , Anda dapat menggunakan operator new
global secara eksplisit, seperti dalam contoh ini:
T *TObject = ::new TObject;
Operator resolusi cakupan (::
) memaksa penggunaan operator global new
.
Baca juga
Ekspresi dengan operator unary
Kata kunci
new
operator dan delete
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk