2014-12-16 12 views
8

Tôi đã thấy một số câu hỏi khác về chủ đề này, nhưng vẫn chưa tìm thấy câu trả lời - Tôi đoán tôi là thiếu một cái gì đó:Làm cách nào để triển khai đa hình với std :: shared_ptr?

tôi định nghĩa hai lớp học thử nghiệm đơn giản:

class TestBase 
{ 

    public: 

    TestBase () { }; 
    ~ TestBase () { }; 

    protected: 

    inline virtual int getInt () 
    { 
     return 0; 
    } 

}; 

class TestDerived : public TestBase 
{ 

    protected: 

    inline int getInt () override 
    { 
     return 1; 
    } 

}; 

tôi tuyên bố typedefs để đơn giản hóa việc sử dụng của họ với std::shared_ptr:

typedef std::shared_ptr<TestBase> spBase; 
typedef std::shared_ptr<TestDerived> spDerived; 

vấn đề: tôi không thể biên dịch mã để sử dụng những shared_ptr tờ khai polymorphi cally, mặc dù base trong tất cả những trường hợp này thực sự là một thể hiện của spDerived:

spBase base; 
spDerived derived = static_cast <spDerived> (base); 

error: no matching function for call to ‘std::shared_ptr::shared_ptr(spBase&)

spDerived derived = dynamic_cast <spDerived> (base); 

error: cannot dynamic_cast ‘base’ (of type ‘spBase {aka class std::shared_ptr}’) to type ‘spDerived {aka class std::shared_ptr}’ (target is not pointer or reference)

spDerived derived = static_pointer_cast <spDerived> (base); 

error: conversion from ‘std::shared_ptr >’ to non-scalar type ‘spDerived {aka std::shared_ptr}’ requested

spDerived derived = dynamic_pointer_cast <spDerived> (base); 

error: conversion from ‘std::shared_ptr >’ to non-scalar type ‘spDerived {aka std::shared_ptr}’ requested

Tôi đang sử dụng C++ 11 trên Ubuntu 14.04 hộp với dây chuyền công cụ GCC mặc định. Trình biên dịch là gcc-4.9. Tôi đang làm gì sai? Không thể sử dụng shared_pointer đa hình?

+4

'static_pointer_cast (cơ sở) ' –

+1

Đây là lý do tại sao typedefs như thế là một ý tưởng khủng khiếp. Chúng chỉ làm cho mã trở nên khó hiểu hơn nhiều. – Puppy

+0

@Puppy - Tôi ghét quá nhiều cách gõ, nhưng tôi e là bạn đã đúng. – Vector

Trả lời

13

Một loại thông qua vào std::static_pointer_caststd::dynamic_pointer_cast như kiểu mẫu đối số đầu tiên là loại loại con trỏ chuyển đổi của bản thân, chứ không phải của thông minh loại con trỏ:

static_pointer_cast<T>(arg); 
       .~~~^ 
       v 
template <class T, class U> 
      .~~~~^ 
      v 
shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r); 


dynamic_pointer_cast<T>(arg); 
       .~~~~^ 
       v 
template <class T, class U> 
      .~~~~^ 
      v 
shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r); 

Với những gì đã nói, bạn có thể gọi nó là như dưới đây:

spBase base = std::make_shared<TestDerived>(); 
spDerived derived = std::dynamic_pointer_cast<spDerived::element_type>(base); 
// or: 
spDerived derived2 = std::dynamic_pointer_cast<TestDerived>(base); 
Các vấn đề liên quan