C++ - 从基类获取派生类的真实类型名

问题描述 投票:0回答:1

例如,我可以使用 CRTP 做这样的事情:

template<typename Self>
struct Sharable {
    int count = 0;

    template<typename... Args>
    static Self *create(Args &&...args) {
        Self *res = new Self(std::forward<Args>(args)...);
        res->count = 1;
        return res;
    }

    Self *dup() {
        ++count;
        return static_cast<Self *>(this);
    }

    void drop() {
        if (--count == 0) {
            delete static_cast<Self *>(this);
        }
    }
};

struct Object : Sharable<Object> {
    int val1;
    Object(int v1) : val1(v1) {}
};

int main() {
    Object *ptr = Object::create(1);
}

但是,问题在于,使用这种模式,如果有一个类继续继承自

Object
类,那么一方面,子类中会出现两个重复的
count
成员,而另一方面另一方面,会存在
create
dup
drop
等方法的多个副本,导致方法调用不明确。

struct Child : Object, Sharable<Child> {
    int val2;
    Child(int v1, int v2) : Object(v1), val2(v2) {}
};

int main() {
    Child *ptr = Child::create(1, 2);
    // error: member 'create' found in multiple base classes of different types
}

我了解到 C++23 中的推导此功能可以做一些相关的事情:

struct SharedMemory {
    std::size_t count = 0;

    template<typename Self>
    Self *dup() {
        ++count;
        return static_cast<Self *>(this);
    }

    template<typename Self>
    void drop() {
        if (--count == 0) {
            delete static_cast<Self *>(this);
        }
    }
};

但是,这似乎只适用于那些非静态方法(

dup
drop
),是否可以对静态方法执行相同的操作? (如果没有C++23特性就可以做到这一点就更好了)

注意:这里,我希望

create
成为
Shared
类的成员方法,而不是在类外将其实现为模板函数,因为我需要以其他方式管理其他一些类的内存(例如,可能有一些其他类继承自另一个基类
Global
而不是
Sharable
,其
create
dup
drop
方法在全局内存上操作)

c++ inheritance reflection crtp c++23
1个回答
0
投票

通过虚拟继承并为 CRTP 提供基础,您可能会这样做:

struct RefCounter
{
    virtual ~RefCounter() = default;
    int count = 1;
};

template<typename Self, typename... Bases>
struct Sharable : protected virtual RefCounter, public Bases...
{

    Sharable(Bases... bases) : Bases(bases)... {}

    template<typename... Args>
    static Self *create(Args &&...args) {
        return new Self(std::forward<Args>(args)...);
    }

    Self *dup() {
        ++count;
        return static_cast<Self *>(this);
    }

    void drop() {
        if (--count == 0) {
            delete static_cast<Self *>(this);
        }
    }
};

struct Object : Sharable<Object> {
    int val1;
    Object(int v1) : val1(v1) {}
};

struct Child : Sharable<Child, Object> {
    int val2;
    Child(int v1, int v2) : Sharable(v1), val2(v2) {}
};

演示

© www.soinside.com 2019 - 2024. All rights reserved.