Các trường tĩnh có được kế thừa không?


102

Khi các thành viên tĩnh được kế thừa, chúng có tĩnh cho toàn bộ hệ thống phân cấp hay chỉ lớp đó, tức là:

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

Tổng số sẽ là 3 trong cả ba trường hợp, hay sẽ là 2 cho SomeClassvà 1 cho SomeDerivedClass?

Câu trả lời:


55

3 trong mọi trường hợp, vì giá trị static int totalđược kế thừa SomeDerivedClasschính xác là biến trong SomeClass, không phải là biến riêng biệt.

Chỉnh sửa: thực sự là 4 trong tất cả các trường hợp, như @ejames đã phát hiện và chỉ ra trong câu trả lời của anh ấy.

Chỉnh sửa: mã trong câu hỏi thứ hai bị thiếu inttrong cả hai trường hợp, nhưng việc thêm nó vào thì nó vẫn OK, tức là:

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

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

hoạt động tốt và với các giá trị khác nhau cho A :: MaxHP và Cat :: MaxHP - trong trường hợp này, lớp con "không kế thừa" tĩnh từ lớp cơ sở, vì có thể nói, nó đang "ẩn" nó bằng từ đồng âm của riêng nó một.


12
Lời giải thích hay, nhưng câu trả lời bằng số thực sự là 4, không phải 3. Xem câu trả lời của tôi ( stackoverflow.com/questions/998247/… )
e.James

3
+1, Điểm tuyệt vời, tôi đang chỉnh sửa câu trả lời để trỏ đến bạn, cảm ơn!
Alex Martelli

1
+1, mặc dù người ta nên nói chính xác hơn "+4 cho bất kỳ thành viên tĩnh nào được khởi tạo thành". Thành viên tĩnh không phải là phạm vi cục bộ cũng không phải là phạm vi không gian tên, vì vậy phải có một định nghĩa ở đâu đó gán giá trị ( không nhất thiết là 0). Nếu không, mã không đáp ứng quy tắc một định nghĩa và sẽ không biên dịch.
Damon

Nhưng nếu một người muốn static int totalkhác biệt cho mỗi lớp dẫn xuất cách duy nhất để đạt được nó để thêm static int totalvào mỗi lớp? Hoặc có thể chỉ sử dụng định nghĩa lớp cơ sở (?), Bởi vì có biến totalnên là thuộc tính của mọi lớp. Mặt khác, nó nên được static.
LRDPRDX

97

Câu trả lời thực sự là bốn trong tất cả các trường hợp, vì việc xây dựng SomeDerivedClasssẽ làm cho tổng số được tăng lên hai lần .

Đây là một chương trình hoàn chỉnh (mà tôi đã sử dụng để xác minh câu trả lời của mình):

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

Và kết quả:

A.total = 4
B.total = 4
C.total = 4

10

Nó là 4 bởi vì khi đối tượng dẫn xuất được tạo, hàm tạo của lớp dẫn xuất sẽ gọi hàm tạo của lớp cơ sở.
Vì vậy, giá trị của biến static được tăng lên hai lần.


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

Nó sẽ là:

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

1

Hàm tạo SomeClass () đang được gọi tự động khi SomeDerivedClass () được gọi, đây là quy tắc C ++. Đó là lý do tại sao tổng số được tăng lên một lần cho mỗi đối tượng SomeClass và sau đó hai lần cho đối tượng SomeDerivedClass. 2x1 + 2 = 4


0

3 trong cả ba trường hợp.

Và đối với câu hỏi khác của bạn, có vẻ như bạn thực sự chỉ cần một biến const thay vì static. Có thể dễ hiểu hơn khi cung cấp một hàm ảo trả về biến mà bạn cần, biến này được ghi đè trong các lớp dẫn xuất.

Trừ khi mã này được gọi trong một đường dẫn quan trọng cần hiệu suất, hãy luôn chọn mã trực quan hơn.


0

Có, lớp dẫn xuất sẽ chứa cùng một biến tĩnh, tức là - tất cả chúng sẽ chứa tổng cộng là 3 (giả sử rằng tổng số đó được khởi tạo bằng 0 ở đâu đó).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.