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:
::optnewnew-placementoptnew-type-idnew-initializeropt
::optnewnew-placementopt(type-id)new-initializeropt

new-placement:
( expression-list )

new-type-id:
type-specifier-seqnew-declaratoropt

new-declarator:
ptr-operatornew-declaratoropt
noptr-new-declarator

noptr-new-declarator:
[expression]attribute-specifier-seqopt
noptr-new-declarator[constant-expression]attribute-specifier-seqopt

new-initializer:
(expression-listopt)
braced-init-list

Keterangan

Jika tidak berhasil, new mengembalikan nol atau melempar pengecualian. Untuk informasi selengkapnya, lihat Operator newdan 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 /GXopsi , , /EHaatau /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 atau type-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, , structatau 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 newyang 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 Tkelas , 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
newoperator dan delete