c++具有镜像层次结构的双重调度

发布于 2024-08-22 21:40:07 字数 966 浏览 11 评论 0原文

以下类层次结构代表抽象资源处理程序和资源层次结构。两者都以接口作为基类。现在想象一下您编写了一个系统,可以在这些接口下实现多个特定的资源系统。这里仅举一个例子。特定的主类创建从 stuff 派生的资源。现在,当创建的资源传递给基接口时,它作为指向基资源类的指针传递,但我想处理特定资源并有权访问其特定属性。

我知道双重调度,但我认为它在这种情况下不起作用。我想阻止 RTTI 和dynamic_casts。您对处理此类案件有什么建议吗?

class resource;

class main_resource_handler
{
public:
   virtual resource* create_resource() = 0;
   virtual void do_some(resource* st) = 0;
};

class resource
{
};

class specific_resource : public resource
{
public:
    int i;
};

class specific_resource_handler : public main_resource_handler
{
public:
    stuff* create_resource) {
        return new specific_resource);
    }
    void do_some(resource* st) {
        // in here i want to work with specific resource
    }
    void do_some(specific_resource* st) {
        // i want to get here
    }
}

main_resource_handler* handler = new specific_resource_handler();
resource* res = handler->create_resource();
handler->do_some(res); /// here

the following class hierarchies represent abstract resource handler and resource hierarchies. Both have the interfaces as base classes. Now imagine you write a system where you can implement multiple specific resource systems under these interfaces. Here is just one example. The specific main class creates the resources derived from stuff. Now when the created resource is handed to the base interface it is handed as a pointer to the base resource class but i want to handle the specific resource and have access to its specific attributes.

I know about double dispatch, but i don't think it works in this case. I would like to prevent RTTI and dynamic_casts. Do you have suggestions as to handle such cases?

class resource;

class main_resource_handler
{
public:
   virtual resource* create_resource() = 0;
   virtual void do_some(resource* st) = 0;
};

class resource
{
};

class specific_resource : public resource
{
public:
    int i;
};

class specific_resource_handler : public main_resource_handler
{
public:
    stuff* create_resource) {
        return new specific_resource);
    }
    void do_some(resource* st) {
        // in here i want to work with specific resource
    }
    void do_some(specific_resource* st) {
        // i want to get here
    }
}

main_resource_handler* handler = new specific_resource_handler();
resource* res = handler->create_resource();
handler->do_some(res); /// here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

寒冷纷飞旳雪 2024-08-29 21:40:07

我认为你没有问正确的问题。

要执行您所要求的操作,您所需要做的就是添加以下内容:

template<typename T>
class helper : public main_resource_handler
{
public:
   virtual resource* create_resource() { return new T; }
   virtual void do_some(resource* st) { do_some_specific(static_cast<T*>(st)); }
private:
   virtual void do_some_specific(T* st) = 0;
};

并更改此内容:

class specific_resource_handler : public helper<specific_resource>
{
private:
   virtual void do_some_specific(T* st) { ... }
}

只有当您可以保证始终调用 do_some 时, static_cast 才是安全的正确类型的处理程序。但是,如果您已经知道它是正确类型的处理程序,则无需进行基类方法调用。因此,大概您想要的是获取某种资源,但不知道其确切类型,并将其传递给适当的处理程序。这更棘手...

I think you're not asking the right question.

To do what you're asking, all you need is to add this:

template<typename T>
class helper : public main_resource_handler
{
public:
   virtual resource* create_resource() { return new T; }
   virtual void do_some(resource* st) { do_some_specific(static_cast<T*>(st)); }
private:
   virtual void do_some_specific(T* st) = 0;
};

And change this:

class specific_resource_handler : public helper<specific_resource>
{
private:
   virtual void do_some_specific(T* st) { ... }
}

The static_cast is only safe if you can guarantee that you will always call do_some on the right type of handler. But if you already know it's the right kind of handler, then there's no need to make a base-class method call. So presumably what you want is to get some sort of resource, not knowing its exact type, and pass it to the appropriate handler. That's trickier...

隱形的亼 2024-08-29 21:40:07

我不确定为什么你需要资源和处理程序 - 看起来你正在暴露与将被封装的东西的额外耦合。如果创建资源只是返回客户端可以直接调用方法的资源,则问题不会存在。

如果您想要安全,请让资源记住创建它的处理程序的地址,然后在 do_some(resource* st) 中进行检查。如果资源是由当前处理程序创建的,并且处理程序只能创建给定类型的资源,则可以安全地对其进行强制转换并调用特定函数。尽管如上所述,如果该函数只是资源上的虚拟函数,那么根据定义,它是类型安全的。

I'm not sure why you need both the resource and the handler - it seems you're exposing an extra coupling to something with would be encapsulated. The problem wouldn't exist if create resource just returned a resource that the client could call methods on directly.

If you want safety, have the resource remember the address of the handler which created it, then check that in do_some(resource* st). If the resource was created by the current handler, and a handler can only create resources of a given kind, then it's safe to cast it and call the specific function. Though as above, if the function was just a virtual function on the resource it would be by definition type safe.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文