Bagaimana menginisialisasi variabel anggota const di kelas?


105
#include <iostream>

using namespace std;
class T1
{
  const int t = 100;
  public:

  T1()
  {

    cout << "T1 constructor: " << t << endl;
  }
};

Ketika saya mencoba untuk menginisialisasi variabel anggota const tdengan 100. Tapi itu memberi saya kesalahan berikut:

test.cpp:21: error: ISO C++ forbids initialization of member t
test.cpp:21: error: making t static

Bagaimana saya bisa menginisialisasi constnilai?


8
dengan c ++ 11 ini dimungkinkan periksa tautan ini stackoverflow.com/questions/13662441/…
Kapil

Jawaban:


122

The constvariabel Menentukan apakah suatu variabel dimodifikasi atau tidak. Nilai konstanta yang ditetapkan akan digunakan setiap kali variabel direferensikan. Nilai yang diberikan tidak dapat diubah selama eksekusi program.

Penjelasan Bjarne Stroustrup merangkumnya secara singkat:

Kelas biasanya dideklarasikan dalam file header dan file header biasanya disertakan ke dalam banyak unit terjemahan. Namun, untuk menghindari aturan linker yang rumit, C ++ mengharuskan setiap objek memiliki definisi yang unik. Aturan itu akan rusak jika C ++ mengizinkan definisi entitas di kelas yang perlu disimpan dalam memori sebagai objek.

Sebuah constvariabel harus dideklarasikan di dalam kelas, tetapi tidak dapat didefinisikan di dalamnya. Kita perlu mendefinisikan variabel const di luar kelas.

T1() : t( 100 ){}

Di sini tugas dilakukan t = 100dalam daftar penginisialisasi, jauh sebelum initilisasi kelas terjadi.


3
Bisakah Anda menjelaskan sedikit tentang pernyataan terakhir yang Here the i = 10 assignment in initializer list happens much before the class initilizaiton occurs.saya tidak mengerti ini. Dan pada dasarnya definisi yang memungkinkan di dalam kelas adalah khusus kompilator, bukan?
Chaitanya

3
Apa i = 10 tugas?
Daniel Daranas

Saya memiliki konstanta di kelas saya yang saya inisialisasi dengan cara di atas. Namun, ketika saya mencoba membuat objek dari kelas itu, itu memberi saya kesalahan mengatakan itu operator = function not founddi VC ++. Apa masalahnya?
Rohit Shinde

4
Saat Anda menggunakan kata-kata persis seseorang tanpa atribusi, itu disebut plagiarisme. Silakan gunakan atribusi yang tepat - lihat stroustrup.com/bs_faq2.html#in-class dan stackoverflow.com/questions/13662441/…
Tanaya

Ya, saya juga sama sekali tidak mengerti kode dalam jawaban - apa itu? Bisakah itu ditempatkan dalam implementasi file cpp?
Tomáš Zato - Kembalikan Monica

50

Nah, Anda bisa membuatnya static:

static const int t = 100;

atau Anda bisa menggunakan penginisialisasi anggota:

T1() : t(100)
{
    // Other constructor stuff here
}

2
Untuk penggunaannya (dan / atau niat), akan jauh lebih baik jika membuatnya statis.
Mark Garcia

@FredLarson Apakah beberapa versi g ++ tidak mengizinkan inisialisasi semacam itu? atau Itu tidak diizinkan sama sekali?
Chaitanya

3
@ Chaitanya: C ++ 11 Penginisialisasi anggota non-statis diimplementasikan dari gcc 4.7.
Jesse Good

@MarkGarcia mengapa jauh lebih baik? itu bisa menjadi persyaratan jika const memberharus dapat diakses dari fungsi / objek lalu mengapa statis?
Asif Mushtaq

Meskipun biasanya menyesatkan untuk memberi contoh statis pemula. Karena, mereka mungkin tidak tahu itu hanya satu untuk semua instance (objek) dari kelas itu.
Muhamed Cicak

30

Ada beberapa cara untuk menginisialisasi anggota const di dalam kelas ..

Pengertian anggota const secara umum membutuhkan inisialisasi variabel juga ..

1) Di dalam kelas, jika Anda ingin menginisialisasi const sintaksnya seperti ini

static const int a = 10; //at declaration

2) Cara kedua bisa

class A
{
  static const int a; //declaration
};

const int A::a = 10; //defining the static member outside the class

3) Jika Anda tidak ingin menginisialisasi di deklarasi, maka cara lain adalah melalui konstruktor, variabel perlu diinisialisasi di daftar inisialisasi (bukan di tubuh konstruktor). Harus seperti ini

class A
{
  const int b;
  A(int c) : b(c) {} //const member initialized in initialization list
};

8
Saya pikir jawaban ini membutuhkan klarifikasi. Penggunaan kata kunci statis untuk anggota kelas tidak menambahkan sintaks sembarangan untuk membuat kompiler senang. Ini berarti ada satu salinan variabel untuk semua contoh objek, konstan atau tidak. Ini adalah pilihan desain yang perlu dipertimbangkan dengan cermat. Programmer mungkin memutuskan bahwa anggota kelas konstan ini masih dapat bervariasi dengan objek yang berbeda, meskipun tetap konstan selama masa pakai objek tertentu.
opetrenko

Setuju .. Saat kita menggunakan statis, itu membuat hanya satu salinannya untuk semua objek .. Seperti yang Anda sebutkan itu pilihan desain. Dalam kasus salinan tunggal untuk semua objek 1 dan 2 harus bekerja. Dalam kasus salinan individu untuk setiap objek, 3 akan bekerja
ravs2627

Jawaban ini menyarankan perubahan sintaks sederhana tanpa konsekuensi - sedangkan mengubahnya menjadi statis tidak.
Isaac Woods

bagaimana jika Anda perlu menggunakan double atau float - apakah ini bagian dari standar C ++ 11?
serup

14

Jika Anda tidak ingin membuat constanggota data di kelas menjadi statis, Anda dapat menginisialisasi constanggota data menggunakan konstruktor kelas. Sebagai contoh:

class Example{
      const int x;
    public:
      Example(int n);
};

Example::Example(int n):x(n){
}

jika ada beberapa constanggota data di kelas Anda dapat menggunakan sintaks berikut untuk menginisialisasi anggota:

Example::Example(int n, int z):x(n),someOtherConstVariable(z){}

3
Saya pikir ini memberikan jawaban yang lebih baik daripada yang diterima ....
Ian

1
Terima kasih atas contoh yang sangat jelas, dan variannya menunjukkan pluralitas! Menghilangkan ambiguitas dan penelitian ekstra / pengguliran di pihak pembaca!
clearlight

13
  1. Anda dapat memutakhirkan kompiler Anda untuk mendukung C ++ 11 dan kode Anda akan bekerja dengan sempurna.

  2. Gunakan daftar inisialisasi dalam konstruktor.

    T1() : t( 100 )
    {
    }

6

Solusi lainnya adalah

class T1
{
    enum
    {
        t = 100
    };

    public:
    T1();
};

Jadi t diinisialisasi ke 100 dan tidak dapat diubah dan bersifat pribadi.


3

Jika anggota adalah Array, itu akan menjadi sedikit rumit dari biasanya:

class C
{
    static const int ARRAY[10];
 public:
    C() {}
};
const unsigned int C::ARRAY[10] = {0,1,2,3,4,5,6,7,8,9};

atau

int* a = new int[N];
// fill a

class C {
  const std::vector<int> v;
public:
  C():v(a, a+N) {}
};

2

Cara lain yang mungkin adalah ruang nama:

#include <iostream>

namespace mySpace {
   static const int T = 100; 
}

using namespace std;

class T1
{
   public:
   T1()
   {
       cout << "T1 constructor: " << mySpace::T << endl;
   }
};

Kerugiannya adalah bahwa kelas lain juga dapat menggunakan konstanta jika mereka menyertakan file header.


1

Ini adalah cara yang tepat untuk dilakukan. Anda dapat mencoba kode ini.

#include <iostream>

using namespace std;

class T1 {
    const int t;

    public:
        T1():t(100) {
            cout << "T1 constructor: " << t << endl;
        }
};

int main() {
    T1 obj;
    return 0;
}

jika Anda menggunakan C++10 Compiler or belowmaka Anda tidak dapat menginisialisasi anggota kontra pada saat deklarasi. Jadi di sini harus membuat konstruktor untuk menginisialisasi anggota data const. Ini juga harus menggunakan daftar penginisialisasi T1():t(100)untuk mendapatkan memori secara instan.


0

Anda dapat menambahkan staticuntuk memungkinkan inisialisasi variabel anggota kelas ini.

static const int i = 100;

Namun, ini tidak selalu merupakan praktik yang baik untuk digunakan di dalam deklarasi kelas, karena semua objek yang dibuat dari kelas itu akan berbagi variabel statis yang sama yang disimpan di memori internal di luar memori lingkup objek yang dibuat.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.