简体   繁体   English

用模板化 function 覆盖虚拟 function

[英]overriding a virtual function with a templated function

I've got a base class with a pure virtual function:我有一个带有纯虚拟 function 的基础 class:

class Allocator 
{
public:
    template< class T >
    virtual T* allocate(T type) = 0;
};

with a derived class with a templated function which the design intent was to override this virtual function:使用派生的 class 和模板化的 function,其设计意图是覆盖此虚拟 function:

class StackAllocator: public Allocator 
{
public: 
    StackAllocator(size_t size, void* stackStart = nullptr);

    template< class T>
    T* allocate(T Type);
};

My design intent was to have allocate override the allocate in Allocator.我的设计意图是让分配覆盖分配器中的分配。 But obviously after reading up on this, i have found the code above will not work.但很明显,在阅读了这个之后,我发现上面的代码不起作用。

I found alot of solutions that involve making the class itself a template, but in this situation i can't do this as the StackAllocator itself needs to be type-agnostic at compile.我发现了很多涉及使 class 本身成为模板的解决方案,但在这种情况下,我不能这样做,因为 StackAllocator 本身在编译时需要与类型无关。 And only the function should deal with the varying types.并且只有 function 应该处理不同的类型。

I found a work-around that involved making an 'allocation' class that was used on a per allocation basis that dealt with the allocation itself, but this seemed wasteful and not very clear in its application so now i'm stuck with simply getting rid of the virtual function and using just the derived class templated function.我找到了一种解决方法,涉及进行“分配” class 用于处理分配本身的每个分配,但这似乎很浪费而且在其应用程序中不是很清楚,所以现在我坚持简单地摆脱的虚拟 function 和仅使用派生的 class 模板 function。

Any ideas how i could do this?任何想法我怎么能做到这一点? or ideas for how to rework my design?或如何修改我的设计的想法? (bear in mind that i will be eventually making many more derived allocators so the base is necessary.) (请记住,我最终将制作更多派生分配器,因此基础是必要的。)

Thanks!谢谢!

Imagine this code worked, how would you use it? 想象一下这段代码是否有效,您将如何使用它?

You'd have something that would be parameterized with the allocator, but since it returns the specific type, that thing would have to know what to do with that specific type. 你有一些东西可以用分配器参数化,但由于它返回特定类型,那东西必须知道如何处理该特定类型。 that means the code is either not generic (which means there's no reason to have a common base class because the code has to be specialized for the specific allocator type) or it is templated to take a matching type from the allocator, but then there's no reason to have a virtual function, since you can just create the very specific factory class (allocator) that matches the templated type of the thing using it. 这意味着代码要么不是通用的(这意味着没有理由拥有公共基类,因为代码必须专门用于特定的分配器类型),或者模仿从分配器中获取匹配类型,但是没有因为你可以创建一个非常具体的工厂类(allocator)来匹配使用它的事物的模板化类型。

You don't really want a templated allocate method - because a specific allocator subclass can't make any type. 您并不真正需要模板化的分配方法 - 因为特定的分配器子类不能生成任何类型。 it can only make its one specific type. 它只能使其成为一种特定类型。 It sounds to me like maybe you want to use partial specialization to achieve this? 听起来对我来说,也许你想使用部分专业来实现这一目标?

http://en.cppreference.com/w/cpp/language/partial_specialization http://en.cppreference.com/w/cpp/language/partial_specialization

and use those partial specializations from something that is templated to the type that you want to create? 并使用那些模板化你想要创建的类型的部分特化?

One possible way of solving this problem is to have a generic allocation function in the base class which simply allocates an array of bytes with some alignment:解决此问题的一种可能方法是在基础 class 中进行通用分配 function,它只是分配带有一些 alignment 的字节数组:

virtual std::byte *allocate(size_t bytes, size_t align) = 0;

This function can be overridden in derived classes.这个 function 可以在派生类中被覆盖。

Then we can have a templated function in the base Allocator class which uses this non-templated function:然后我们可以在基本Allocator class 中有一个模板化的 function,它使用这个非模板化的 function:

// Argument 'n' here can be the number of allocated instances...
// Not Necessary but might be useful
template<class T>
T *Allocator::allocate(size_t n)
{
  return (T *) allocate(sizeof(T) * n, alignof(T));
}

This way you have made it possible for derived classes to specifically implement their allocation strategy while retaining the typed-allocation API.这样,您就可以让派生类在保留类型分配 API 的同时专门实现其分配策略。 The only caveat with this solution is that you will need to add using Allocator::allocate;此解决方案的唯一警告是您需要using Allocator::allocate; somewhere in the derived class declaration (credits to Igor Tandetnik for this, explained here ) but this is a simple thing to do.在派生的 class 声明中的某处(为此归功于Igor Tandetnik在此处解释)但这是一件简单的事情。

Please keep in mind that using non-aligned pointers for arbitrary types is undefined behaviour and could have various undesireable effects: What exactly is an 'aligned pointer'?请记住,对任意类型使用非对齐指针是未定义的行为,并且可能会产生各种不良影响: “对齐指针”到底是什么?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM