Pertanyaan Apakah tanda kurung setelah nama jenis membuat perbedaan dengan yang baru?


Jika 'Test' adalah kelas biasa, apakah ada perbedaan antara:

Test* test = new Test;

dan

Test* test = new Test();

891
2018-03-06 19:39


asal


Jawaban:


Mari kita bertele-tele, karena ada perbedaan yang benar-benar dapat memengaruhi perilaku kode Anda. Banyak dari yang berikut ini diambil dari komentar yang dibuat untuk sebuah Artikel "Old New Thing".

Terkadang memori yang dikembalikan oleh operator baru akan diinisialisasi, dan kadang-kadang tidak akan tergantung pada apakah jenis yang Anda barukan adalah a POD (data lama biasa), atau apakah itu kelas yang berisi anggota POD dan menggunakan konstruktor default yang dibuat oleh compiler.

  • Di C ++ 1998 ada 2 jenis inisialisasi: nol dan default
  • Di C ++ 2003, jenis inisialisasi ketiga, inisialisasi nilai ditambahkan.

Menganggap:

struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m

Dalam kompiler C ++ 98, hal-hal berikut harus terjadi:

  • new A   - nilai tak tentu
  • new A() - nol-menginisialisasi

  • new B   - konstruksi standar (B :: m tidak terinisialisasi)

  • new B() - konstruksi standar (B :: m tidak terinisialisasi)

  • new C   - konstruksi standar (C :: m adalah nol-diinisialisasi)

  • new C() - konstruksi standar (C :: m adalah nol-diinisialisasi)

Dalam compiler konformal C ++ 03, hal-hal harus bekerja seperti:

  • new A    - nilai tak tentu
  • new A()  - nilai-menginisialisasi A, yang merupakan inisialisasi-nol karena ini adalah POD.

  • new B    - default-inisialisasi (daun B :: m tidak diinisialisasi)

  • new B()  - nilai-menginisialisasi B yang nol-menginisialisasi semua bidang sejak ctor standarnya adalah kompilator yang dihasilkan sebagai lawan dari yang ditentukan pengguna.

  • new C    - default-menginisialisasi C, yang memanggil ktor default.

  • new C()  - menginisialisasi nilai C, yang memanggil ktor default.

Jadi di semua versi C ++ ada perbedaan antara new A dan new A() karena A adalah POD.

Dan ada perbedaan perilaku antara C ++ 98 dan C ++ 03 untuk kasus ini new B().

Ini adalah salah satu sudut berdebu C ++ yang dapat membuat Anda gila. Ketika membangun sebuah objek, terkadang Anda ingin / membutuhkan para orang tua, terkadang Anda benar-benar tidak dapat memilikinya, dan terkadang itu tidak masalah.


860
2018-03-06 21:01



new Thing(); eksplisit bahwa Anda menginginkan konstruktor yang disebut sedangkan new Thing; dianggap menyiratkan bahwa Anda tidak keberatan jika konstruktor tidak dipanggil.

Jika digunakan pada struct / class dengan konstruktor yang ditentukan pengguna, tidak ada perbedaan. Jika dipanggil pada suatu struct / class sepele (mis. struct Thing { int i; };) kemudian new Thing; seperti malloc(sizeof(Thing)); sedangkan new Thing(); seperti calloc(sizeof(Thing)); - mendapat nol diinisialisasi.

Gotcha terletak di antara:

struct Thingy {
  ~Thingy(); // No-longer a trivial class
  virtual WaxOn();
  int i;
};

Perilaku new Thingy; vs new Thingy(); dalam hal ini berubah antara C ++ 98 dan C ++ 2003. Lihat penjelasan Michael Burr tentang bagaimana dan mengapa.


49
2018-02-15 19:57



Tidak, mereka sama. Tetapi ada perbedaan antara:

Test t;      // create a Test called t

dan

Test t();   // declare a function called t which returns a Test

Ini karena aturan C ++ (dan C) dasar: Jika sesuatu mungkin merupakan deklarasi, maka itu adalah deklarasi.

Edit: Re inisialisasi masalah mengenai POD dan data non-POD, sementara saya setuju dengan semua yang telah dikatakan, saya hanya ingin menunjukkan bahwa masalah ini hanya berlaku jika hal yang baru atau dibangun tidak memiliki user- konstruktor didefinisikan. Jika ada konstruktor seperti itu akan digunakan. Untuk 99,99% dari kelas yang dirancang secara bijaksana akan ada konstruktor seperti itu, sehingga masalah dapat diabaikan.


16
2018-03-06 19:42



Secara umum kita memiliki inisialisasi default dalam kasus pertama dan inisialisasi nilai dalam kasus kedua.

Sebagai contoh: dalam kasus dengan int (POD type):

  • int* test = new int - kami memiliki inisialisasi dan nilai * test dapat berupa apa saja.

  • int* test = new int() - * Tes akan memiliki nilai 0.

perilaku berikutnya tergantung dari Uji jenis Anda. Kami memiliki kasus defferent: Test memiliki konstruktor penghinaan, Test telah menghasilkan konstruktor default, Test mengandung anggota POD, non POD member ...


16
2018-03-06 20:00



Dengan asumsi bahwa Tes adalah kelas dengan konstruktor yang ditentukan, tidak ada perbedaan. Bentuk terakhir membuatnya sedikit lebih jelas bahwa konstruktor Test berjalan, tapi itu saja.


10
2018-03-06 19:42