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是一个正在运行的例子。

相关问题