Apakah bidang statis diwariskan?

102

Ketika anggota statis diwariskan, apakah mereka statis untuk seluruh hierarki, atau hanya kelas itu, yaitu:

class SomeClass
{
public:
    SomeClass(){total++;}
    static int total;
};

class SomeDerivedClass: public SomeClass
{
public:
    SomeDerivedClass(){total++;}
};

int main()
{
    SomeClass A;
    SomeClass B;
    SomeDerivedClass C;
    return 0;
}

akan total menjadi 3 dalam ketiga contoh, atau apakah itu 2 untuk SomeClassdan 1 untuk SomeDerivedClass?

BartoszKP
sumber

Jawaban:

55

3 dalam semua kasus, karena yang static int totaldiwarisi oleh SomeDerivedClasspersis sama dengan yang ada SomeClass, bukan variabel yang berbeda.

Edit: sebenarnya 4 dalam semua kasus, seperti yang dilihat @ejames dan ditunjukkan dalam jawabannya, yaitu lihat.

Edit: kode dalam pertanyaan kedua tidak ada intdalam kedua kasus, tetapi menambahkannya membuatnya OK, yaitu:

class A
{
public:
    static int MaxHP;
};
int A::MaxHP = 23;

class Cat: A
{
public:
    static const int MaxHP = 100;
};

berfungsi dengan baik dan dengan nilai yang berbeda untuk A :: MaxHP dan Cat :: MaxHP - dalam hal ini subkelas "tidak mewarisi" statis dari kelas dasar, karena, bisa dikatakan, itu "menyembunyikan" dengan homonimnya sendiri satu.

Alex Martelli
sumber
12
Penjelasan yang bagus, tetapi jawaban numerik sebenarnya adalah 4, bukan 3. Lihat jawaban saya ( stackoverflow.com/questions/998247/… )
e.James
3
+1, Poin bagus, saya sedang mengedit jawaban untuk menunjuk ke jawaban Anda, terima kasih!
Alex Martelli
1
+1, meskipun seseorang seharusnya lebih tepat mengatakan "+4 ke apa pun anggota statis tersebut diinisialisasi". Anggota statis bukanlah lingkup lokal maupun lingkup namespace, jadi harus ada definisi di suatu tempat yang memberikan nilai ( tidak harus nol). Jika tidak, kode tidak memenuhi aturan satu definisi dan tidak akan dapat dikompilasi.
Damon
Tetapi jika seseorang ingin static int totalberbeda untuk setiap kelas turunan satu-satunya cara untuk mencapainya dengan menambahkan static int totalke setiap kelas? Atau mungkinkah hanya menggunakan definisi kelas dasar (?), Karena variabel totalharus menjadi properti setiap kelas. Di sisi lain seharusnya begitu static.
LRDPRDX
97

Jawabannya sebenarnya adalah empat dalam semua kasus, karena pembangunan SomeDerivedClassakan menyebabkan total bertambah dua kali .

Berikut adalah program lengkap (yang saya gunakan untuk memverifikasi jawaban saya):

#include <iostream>
#include <string>

using namespace std;

class SomeClass
{
    public:
        SomeClass() {total++;}
        static int total;
        void Print(string n) { cout << n << ".total = " << total << endl; }
};

int SomeClass::total = 0;

class SomeDerivedClass: public SomeClass
{
    public:
        SomeDerivedClass() {total++;}
};

int main(int argc, char ** argv)
{
    SomeClass A;
    SomeClass B;
    SomeDerivedClass C;

    A.Print("A");
    B.Print("B");
    C.Print("C");

    return 0;
}

Dan hasilnya:

A.total = 4
B.total = 4
C.total = 4
e. James
sumber
10

Ini adalah 4 karena ketika objek turunan dibuat, konstruktor kelas turunan memanggil konstruktor kelas dasar.
Jadi nilai variabel statis bertambah dua kali.

VenuGopal
sumber
5
#include<iostream>
using namespace std;

class A
{
public:
    A(){total++; cout << "A() total = "<< total << endl;}
    static int total;
};

int A::total = 0;

class B: public A
{
public:
    B(){total++; cout << "B() total = " << total << endl;}
};

int main()
{
    A a1;
    A a2;
    B b1;

    return 0;
}

Itu akan:

A() total = 1
A() total = 2
A() total = 3
B() total = 4
rocky4android
sumber
1

Konstruktor SomeClass () dipanggil secara otomatis ketika SomeDerivedClass () dipanggil, ini adalah aturan C ++. Itulah mengapa total bertambah satu kali per setiap objek SomeClass, lalu dua kali untuk objek SomeDerivedClass. 2x1 + 2 = 4

Darko Maksimovic
sumber
0

3 dalam ketiga contoh.

Dan untuk pertanyaan Anda yang lain, sepertinya Anda benar-benar hanya membutuhkan variabel const, bukan statis. Mungkin lebih jelas untuk menyediakan fungsi virtual yang mengembalikan variabel yang Anda butuhkan yang diganti dalam kelas turunan.

Kecuali kode ini dipanggil di jalur kritis di mana kinerja diperlukan, selalu pilih kode yang lebih intuitif.

adzm
sumber
0

Ya, kelas turunan akan berisi variabel statis yang sama, yaitu - semuanya akan berisi total 3 (dengan asumsi bahwa total diinisialisasi ke 0 di suatu tempat).

Niki Yoshiuchi
sumber