基类中只有一个方法可以分配给子类

Having a single method in a base class able to allocate for child classes

本文关键字:分配 子类 方法 有一个 基类      更新时间:2023-10-16

我正在尝试使用一个公共的基类/辅助类来为调用类分配shared_ptrs,但我在使它在派生类中工作时遇到了问题。

#include <memory>
template<typename T>
struct SPAlloc {
    virtual ~SPAlloc() {}
    template<typename ...Args>
    static std::shared_ptr<T>
    Alloc(Args&&... params) {
        return std::make_shared<T>(std::forward<Args>(params)...);
    }

    template<class U, typename ...Args>
    static std::shared_ptr<U>
    Alloc(Args&&... params) {
        return std::make_shared<U>(std::forward<Args>(params)...);
    }
};
class Base : public SPAlloc<Base> {
public:
    virtual ~Base() {};
};
class Child : public Base {
public:
    virtual ~Child() {};
};
typedef std::shared_ptr<Base> pBase;
typedef std::shared_ptr<Child> pChild;
int main() {
    pBase base = Base::Alloc();
    pChild child = Child::Alloc();
}

我知道class Base : public SPAlloc<Base>意味着模板中的T将是Base,这就是我创建第二个Alloc的原因。第二个alloc需要像Child::Alloc<Child>()一样调用。

有没有一种方法可以编写这个Alloc,这样编译器就可以推断出我调用Alloc的类?

简短回答:没有。

长话短说:关键是,除非明确告知,否则Alloc不知道Child,那么这些信息从哪里来呢?对Child::Alloc()的调用是对Base::Alloc()的调用,这是对SPAlloc<Base>::Alloc()的调用,在那里,关于Child的所有信息都丢失了。

最简单的解决方案是使用一个自由函数,但该函数已经存在,它被称为:std::make_shared。也许可以考虑直接使用它,并完全避免SPAlloc的麻烦。

或者,如果您想为每个子级覆盖SPAlloc<T>::Alloc(),则根本不需要基类SPAlloc,只需将方法添加到每个类中,这可能比使用基类更容易。

如果你真的想这样做,你需要所有的对象从Spalloc继承,并将它们本身作为模板参数,甚至是你的子类:

class Child : public SPAlloc<Child>, public Base {
public:
    virtual ~Child() {};
public:
   using SPAlloc<Child>::Alloc;
};

您也可以简单地使用std::make_shared:(