"nhưng có cách nào để chuyển đổi lại: từ cha mẹ, được lấy từ trẻ, cung cấp lớp con?"
Có, như đã đề cập trong các câu trả lời khác, có hai cách để thực hiện việc này.
Child * old_child = dynamic_cast<Child*>(parent);
Kết quả của dynamic_cast<>
thể được kiểm tra trong thời gian chạy, do đó bạn có thể xác định xem đối tượng parent
thực sự đại diện cho một trường hợp Child
:
if(!old_child) {
// parent is not a Child instance
}
Cũng lưu ý để có được điều này hoạt động bình thường, các lớp trong câu hỏi cần phải có một vtable, rằng RTTI thực sự có thể xác định mối quan hệ của họ.Hình thức đơn giản nhất để đạt được điều này, là cho lớp Parent
một hàm destructor ảo
class Parent {
public:
virtual ~Parent() {}
// or
// virtual ~Parent() = default;
// as suggested for latest standards
};
LƯU Ý:
Nếu đây nên áp dụng cho một quyết định thiết kế chung, tôi sẽ mạnh mẽ bỏ qua nó. Thay vào đó, hãy sử dụng pure virtual interfaces để đảm bảo được triển khai hoặc không.
Cách thứ hai của static_cast<>
có thể được sử dụng trong các môi trường, nơi bạn cũng biết rằng parent
thực sự là một đứa trẻ. Hình thức đơn giản của việc này là CRTP, nơi Parent
mất lớp kế thừa như một mẫu tham số
template <class Derived>
class Parent {
void someFunc() {
static_cast<Derived*>(this)->doSomething();
}
};
class Child : public Parent<Child> {
public:
void doSomething();
};
Hiệu lực của một instatiation của Parent<>
và static_cast<>
sẽ được kiểm tra tại thời gian biên dịch.
LƯU Ý:
lợi thế khác là bạn có thể sử dụng một giao diện cho nguồn gốc mà làm cho sử dụng
- thành viên lớp tĩnh của
Derived
typedef
's cung cấp bởi Derived
- .. các đặc điểm lớp học khác, có thể được kiểm tra tại thời điểm biên dịch
'Child * old_child = dynamic_cast (mẹ); ' –
juanchopanza
Yes. ['static_cast <>' và 'dynamic_cast <>'] (http://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast) có thể được sử dụng để làm điều này. –
Cảm ơn rất nhiều !!! – user2160982