정적 필드가 상속됩니까?


102

정적 멤버가 상속되면 전체 계층 구조 또는 해당 클래스에 대해 정적입니다. 즉 :

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과 일을 SomeDerivedClass?

답변:


55

3 모든 경우에 static int total상속 된는 고유 변수가 아니라 SomeDerivedClass에서 정확히 하나 SomeClass이기 때문입니다.

편집 : @ejames가 그의 대답에서 발견하고 지적했듯이 모든 경우에 실제로 4 입니다.

편집 : 두 번째 질문의 코드는 int두 경우 모두 누락 되었지만 추가하면 괜찮습니다.

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

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

A :: MaxHP 및 Cat :: MaxHP에 대해 서로 다른 값을 사용하여 잘 작동합니다.이 경우 하위 클래스는 기본 클래스에서 정적을 "상속하지"않습니다. 하나.


12
좋은 설명이지만 숫자 대답은 실제로 3이 아니라 4입니다. 내 대답을 참조하십시오 ( stackoverflow.com/questions/998247/… )
e.James

3
+1, 훌륭합니다. 답변을 수정하고 있습니다. 감사합니다.
Alex Martelli

1
+1, "정적 멤버가 초기화되는 모든 항목에 +4"를 더 정확하게 말해야합니다. 정적 멤버는 로컬 범위도 네임 스페이스 범위도 아니므로 값을 할당하는 정의가 있어야합니다 ( 반드시 0이 아님). 그렇지 않으면 코드가 단일 정의 규칙을 충족하지 않고 컴파일되지 않습니다.
Damon

그러나 static int total각 파생 클래스에 대해 구별 되기를 원한다면 static int total각 클래스 에 추가하는 유일한 방법은 무엇입니까? 또는 변수 total를 갖는 것은 모든 클래스의 속성이어야 하므로 기본 클래스 정의 (?) 만 사용할 수 있습니다. 반면에 static.
LRDPRDX

97

의 구성으로 인해 합계가 두 번 증가하기 때문에 답은 실제로 모든 경우에 4 입니다 .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

10

파생 객체가 생성 될 때 파생 클래스 생성자가 기본 클래스 생성자를 호출하기 때문에 4입니다.
따라서 정적 변수의 값은 두 번 증가합니다.


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

다음과 같습니다.

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

1

SomeClass () 생성자는 SomeDerivedClass ()가 호출 될 때 자동으로 호출됩니다. 이것은 C ++ 규칙입니다. 이것이 합계가 각 SomeClass 객체마다 한 번씩 증가한 다음 SomeDerivedClass 객체에 대해 두 번 증가하는 이유입니다. 2x1 + 2 = 4


0

세 가지 경우 모두 3입니다.

그리고 다른 질문에 대해서는 정적 대신 const 변수가 정말로 필요한 것 같습니다. 파생 클래스에서 재정의 된 필요한 변수를 반환하는 가상 함수를 제공하는 것이 더 자명 할 수 있습니다.

성능이 필요한 중요한 경로에서이 코드가 호출되지 않는 한 항상 더 직관적 인 코드를 선택하십시오.


0

예, 파생 클래스는 동일한 정적 변수를 포함합니다. 즉, 모두 합계에 대해 3을 포함합니다 (총계가 어딘가에 0으로 초기화되었다고 가정).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.