เขตข้อมูลคงที่สืบทอดมาหรือไม่


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และ 1 สำหรับSomeDerivedClass?

คำตอบ:


55

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 - ในกรณีนี้คลาสย่อยจะ "ไม่สืบทอด" สแตติกจากคลาสฐานดังนั้นหากต้องการพูดจึงเป็นการ "ซ่อน" ด้วยคำพ้องเสียงของตัวเอง หนึ่ง.


12
คำอธิบายที่ดี แต่คำตอบที่เป็นตัวเลขจริงๆแล้วคือ 4 ไม่ใช่ 3 ดูคำตอบของฉัน ( stackoverflow.com/questions/998247/… )
เจมส์

3
+1 จุดยอดเยี่ยมฉันกำลังแก้ไขคำตอบเพื่อชี้ไปที่คุณขอบคุณ!
Alex Martelli

1
+1 แม้ว่าอีกคนควรพูดว่า "+4 ถึงสิ่งที่สมาชิกคงที่เริ่มต้น" อย่างถูกต้อง สมาชิกแบบคงที่ไม่ใช่ขอบเขตโลคัลหรือขอบเขตเนมสเปซดังนั้นจึงต้องมีนิยามที่กำหนดค่า ( ไม่จำเป็นต้องเป็นศูนย์) มิฉะนั้นโค้ดจะไม่เป็นไปตามกฎนิยามเดียวและจะไม่รวบรวม
Damon

แต่ถ้าใครต้องการstatic int totalความแตกต่างสำหรับแต่ละคลาสที่ได้รับมาวิธีเดียวที่จะบรรลุเพื่อเพิ่มstatic int totalในแต่ละคลาส? หรือเป็นไปได้ที่จะใช้เฉพาะนิยามคลาสพื้นฐาน (?) เนื่องจากการมีตัวแปรtotalควรเป็นคุณสมบัติของทุกคลาส บนมืออื่น ๆ staticที่ควรจะเป็น
LRDPRDX

97

คำตอบคือจริงสี่ในทุกกรณีตั้งแต่การก่อสร้าง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.