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?

Chaitanya
sumber
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.

Dinkar Thakur
sumber
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
}
Fred Larson
sumber
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
};
ravs2627
sumber
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){}
GANESH BK
sumber
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 )
    {
    }
borisbn
sumber
6

Solusi lainnya adalah

class T1
{
    enum
    {
        t = 100
    };

    public:
    T1();
};

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

Musky
sumber
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) {}
};
Viet Anh Do
sumber
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.

Baran
sumber
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.

Penjudi Aziz
sumber
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.

dhokar.w
sumber