Статические поля наследуются? - PullRequest
93 голосов
/ 16 июня 2009

Когда статические члены наследуются, являются ли они статическими для всей иерархии, или только для этого класса, т.е.

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;
}

будет 3 во всех трех случаях или 2 для SomeClass и 1 для SomeDerivedClass?

Ответы [ 7 ]

92 голосов
/ 16 июня 2009

Ответ на самом деле четыре во всех случаях, поскольку построение SomeDerivedClass приведет к увеличению общей суммы в два раза .

Вот полная программа (которую я использовал для проверки своего ответа):

#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;
}

И результаты:

A.total = 4
B.total = 4
C.total = 4
48 голосов
/ 16 июня 2009

3 во всех случаях, поскольку static int total, унаследованный SomeDerivedClass, является точно таким же, как в SomeClass, а не отдельной переменной.

Редактировать: фактически 4 во всех случаях, как @ejames заметил и указал в своем ответе, который видит.

Редактировать: код во втором вопросе пропускает int в обоих случаях, но при добавлении его все в порядке, т. Е .:

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

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

работает нормально и с разными значениями для A :: MaxHP и Cat :: MaxHP - в этом случае подкласс «не наследует» статический элемент от базового класса, поскольку, так сказать, он «скрывает» его с помощью свой собственный одноименный.

7 голосов
/ 12 января 2011

Это 4, потому что когда создается производный объект, конструктор производного класса вызывает конструктор базового класса.
Таким образом, значение статической переменной увеличивается в два раза.

4 голосов
/ 30 мая 2012
#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;
}

Это будет:

A() total = 1
A() total = 2
A() total = 3
B() total = 4
1 голос
/ 14 февраля 2011

SomeClass () конструктор вызывается автоматически при вызове SomeDerivedClass (), это правило C ++. Вот почему сумма увеличивается один раз для каждого объекта SomeClass, а затем дважды для объекта SomeDerivedClass. 2x1 +-= 4

0 голосов
/ 16 июня 2009

Да, производный класс будет содержать одну и ту же статическую переменную, т. Е. Все они будут содержать 3 для общего количества (при условии, что общее значение было инициализировано где-то 0).

0 голосов
/ 16 июня 2009

3 во всех трех случаях.

И для вашего второго вопроса, похоже, вам просто нужна переменная const вместо static. Может оказаться более понятным предоставить виртуальную функцию, которая возвращает нужную вам переменную, которая переопределяется в производных классах.

Если этот код не вызывается по критическому пути, где необходима производительность, всегда выбирайте более интуитивный код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...