0

我舉了一個簡單的例子來說明我的問題。這是基類。當它被轉換爲基類時,派生類的成員可以被訪問嗎?

#include <mutex> 
#include <atomic> 

class Task 
{ 
public: 
    Task() 
    { 
     Empty.store(true); 
    } 
    std::mutex Access; 
    std::atomic<bool> Empty; 
    virtual void Work() = 0; 
}; 

這是派生類。

#include <stdlib.h> 

class ExampleTask : public Task 
{ 
public: 
    void Work() 
    { 
     for(int i = 0; i < 16; ++i) 
     { 
      Data[i] = rand(); 
     } 
    } 
private: 
    int Data[16]; 
}; 

正如你所看到的,這個例子是關於將會異步完成的任務或工作。想象一下,有一個Task的隊列和一堆工作線程,也許目標機器上的每個CPU核心都有一個線程。

任務隊列將轉儲的任務存儲到其基類中,以便工作線程可以從隊列中選取下一個作業並調用Work()

std::list<Task*> Queue; 

ExampleTask *example = new ExampleTask(); 
Queue.push_back((Task*)example); 

工作線程然後將獲取第一個任務,將其從隊列中刪除,並對其進行處理。

while(true) 
{ 
    Task *current = Queue.front(); 
    Queue.erase(Queue.begin()); 
    current->Work(); 
} 

這個概念會起作用嗎?當調用current->Work()時,即使我處理一個指向基類的指針,也可以訪問Data

+3

是的,這是可行的,歡迎來到多態:)而且你甚至不需要'Queue.push_back((任務*)例子)中的強制轉換;''。這些轉換是隱含的。 – jrok

+0

@jrok這是否暗示我可以從第三方庫中獲取任何類,從中繼承並覆蓋一些函數,將實例化對象轉換回基類,並讓庫在不知道的情況下使用它? – danijar

+1

只要你覆蓋虛擬方法,它就可以工作。 –

回答

0

是的:引用/指向基類的指針可隱式轉換爲指向派生類的指針/引用。這究竟是如何CRTP和靜態多態性的工作原理:

template<typename T> 
struct CRTP_base 
{ 
    void execute() 
    { 
     static_cast<T*>(this)->f(); //The instance is casted to the known derived class, and we use the derived class function f. 
    } 
}; 

struct Foo : public CRTP_base<Foo> 
{ 
    void f() 
    { 
     std::cout << "Wow, compile-time resolved polymorphism!" << std::endl; 
    } 
}; 

int main() 
{ 
    Foo my_foo_instance; 
    CRTP_base<Foo>& base_reference = my_foo_instance; 
    base_reference.execute(); 
}; 

此打印:

哇,編譯時間分辨多態性!

Here是一個正在運行的例子。

相關問題