gpt4 book ai didi

每个派生类的 C++ 分离静态字段

转载 作者:太空狗 更新时间:2023-10-29 22:57:13 25 4
gpt4 key购买 nike

考虑了很长一段时间我的问题的解决方案,当我没有其他想法只能在这里问的时候,我终于明白了。

我有以下问题。

简短版本。如何从基类继承静态字段,但使其在每个派生类中都是唯一的,并保持将这些类向上转换为父类的可能性?

长版。我需要为一组类创建某种基本接口(interface)。每个此类都需要有一个静态字段和一个静态方法。但是我希望能够将所有这些类作为参数传递给一个使用这些静态成员的通用函数。所以我在考虑从一个基类继承它们。

但是我当然不能简单地继承静态成员并期望它们在每个子类中都是唯一的。我试图使用 Curiously Recurring Template Pattern (CRTP),但它迫使我也制作这个通用函数模板,并在每次调用时直接给它类名。这对我不利。

此外,当使用多于一层的继承时(即,当我想从派生自该模板基类的类中派生出一个类时),我也遇到了使 CRTP 工作的问题。有什么办法可以达到我的需要吗?

我知道已经有人问过类似的问题,但其中大多数作者对 CRTP 很满意。对我来说,这似乎还不够好。

 //pseudo-code for what I need, doesn't work of course
class Base {
public:
static int x;
static int GetX() {return x;}
}

class Derived : public Base {};
class NextDerived : public Derived {};
class NextDerived2 : public Derived {};

void Foo(Base& a) {a.x = 10;}

int main {
NextDerived d;
NextDerived2 d2;
Foo(d);
Foo(d2); //both Foos modify different static variables
}

//CRTP attempt
template <class C>
class Base {
public:
static int x;
static int GetX() {return x}
};

class Derived : public Base<Derived> {};
int Derived::x = 0;

template <class C>
void Foo(Base<C>& b) {
b.x = 10;
return;
};

int main() {
Derived d;

Foo<Derived>(d);
}

最佳答案

请记住,还必须定义静态变量。因此,对于每个需要单独静态变量的派生类型,您也需要对其进行定义。

相反,您可以使用 std::map和一个 type-id 散列来做类似的事情而不需要弄乱你的基类。此外,这允许您使用任何类型,例如:

#include <iostream>
#include <map>
#define out(v) std::cout << v << std::endl

static std::map<std::size_t, int> ExsAndOhs;

template < typename T >
static std::size_t type_id() // in case you don't want RTTI on
{
static char tid;
return reinterpret_cast<std::size_t>(&tid);
}

template < typename T >
void Foo(int _x) { ExsAndOhs[type_id<T>()] = _x; }

template < typename T >
void Foo(T& obj, int _x) { ExsAndOhs[type_id<T>()] = _x; }

template < typename T >
void Print() { out(ExsAndOhs[type_id<T>()]); }

template < typename T >
void Print(T& obj) { out(ExsAndOhs[type_id<T>()]); }


class Base {};
class Derived : public Base {};
class D2 : public Base {};

int main(int argc, char* argv[])
{
// using explicit templates
Foo<Base>(100);
Foo<Derived>(10);
Foo<D2>(42);
Foo<long>(65535);
Foo<int>(1955);
Print<Base>();
Print<Derived>();
Print<D2>();
Print<long>();
Print<int>();


Base b;
Derived d;
D2 d2;
int x = 1;
long y = 1;
// using template deduction
Foo(b, 10);
Foo(d, 42);
Foo(d2, 100);
Print(b);
Print(d);
Print(d2);
Print(x); // still prints 1955
Print(y); // still prints 65535

return 0;
}

这也避免了为每个派生类声明静态成员的需要。

对于您的特定用例,这可能不是一个好的解决方案,但它是实现您要求的替代方案。

希望对您有所帮助。

关于每个派生类的 C++ 分离静态字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45423024/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com