2012-06-06 73 views
15

Tôi muốn có một lớp cơ sở có trường cố định (như một ID duy nhất được liên kết với lớp không thể sửa đổi sau thời gian biên dịch). Cho đến nay tuyên bố static const sẽ là tốt. Bây giờ, tôi muốn kế thừa lớp cơ sở này và đảm bảo rằng các con của lớp này có cùng một trường, nhưng với các giá trị riêng của chúng. Tôi có thể làm cái này như thế nào?Có thể khai báo giá trị hằng số tĩnh ảo trong lớp C++ không?

Hãy nói rằng, tôi muốn có một lớp cơ sở gọi là Base với một lĩnh vực ID chứa giá trị int của 0. Sau đó, tôi muốn có các lớp A, BC, tất cả trong số đó là trẻ em công chúng của Base và tôi muốn đảm bảo rằng những đứa trẻ này cũng sẽ có các trường ID với giá trị tương ứng là 1, 2 và 3 (bằng cách 'đảm bảo', ý tôi là có lỗi như trình biên dịch nếu chúng không ' t có một ID được khai báo rõ ràng).

Nếu tôi có thể quản lý để xây dựng kịch bản này, mong đợi của tôi sẽ là yêu cầu các ID lĩnh vực một con trỏ Base*, tôi sẽ nhận được các giá trị khác nhau tùy thuộc xem con trỏ đã được tạo ra như new A(), new B() hoặc new C().

Dự đoán của tôi là khai báo IDvirtual static const, điều này tất nhiên không có ý nghĩa và đưa ra lỗi trình biên dịch.

Nhưng sau đó tôi có thể làm gì để đạt được kết quả được mô tả? (Điều duy nhất mà tôi có thể tưởng tượng là khai báo ID như một hàm ảo trả về một số nguyên và sau đó mã hóa cứng giá trị vào phần thân hàm, nhưng tôi đang tìm kiếm một thứ gì đó thanh lịch hơn.)

Cảm ơn bạn nâng cao!

+0

Polymorphism chỉ hoạt động cho các chức năng thành viên và không hợp lệ cho các thành viên dữ liệu. – Mahesh

+0

Tôi đã viết một giải pháp thay thế dựa trên các mẫu: http://stackoverflow.com/a/36797199/1529139 – 56ka

Trả lời

15

Phương thức static không thể là virtual và không có thành viên dữ liệu nào có thể là virtual.

Nhưng bạn có thể ẩn các trường static trong các lớp dẫn xuất và sử dụng phương thức virtual để trả lại chúng.

class A 
{ 
public: 
    static const int ID = 0; 
    virtual int getID() { return A::ID; } 
}; 
class B : A 
{ 
public: 
    static const int ID = 1; 
    virtual int getID() { return B::ID; } 
}; 

Alternative:

class A 
{ 
public: 
    A(int id = 0) : ID(id) {} 
    const int ID; 
    getID() { return ID; } 
}; 
class B : public A 
{ 
public: 
    B() : A(1) {} 
}; 
+0

Vâng, đây là giải pháp duy nhất mà tôi biết cho đến nay. Nhưng không có cách nào để giải quyết điều này một cách thanh lịch/đơn giản hơn? Hoặc nếu đây là cách duy nhất để đi, thì câu hỏi của tôi là đúng hơn: lý do tại sao thừa kế ảo làm việc với các hàm sẽ không làm việc với các thành viên dữ liệu là gì? Tôi hiểu tại sao thực tế 'tĩnh ảo' sẽ không có ý nghĩa, nhưng tôi thực sự không thể hiểu tại sao, giả sử, một trường' int ảo int' đơn giản sẽ không có ý nghĩa ... –

+0

@ SiskaÁdám vì hành vi đa hình không phải là được xác định cho các thành viên dữ liệu. Đó là cách ngôn ngữ được thiết kế. Và đó là một điều tốt về IMO. –

+0

@ SiskaÁdám Tôi đăng một giải pháp thay thế, nhưng tôi vẫn tìm được giải pháp đầu tiên tốt hơn. –

Các vấn đề liên quan