gpt4 book ai didi

c++ - 最小实例化类对象,查询getInstance()时,基于继承

转载 作者:行者123 更新时间:2023-11-30 05:15:18 25 4
gpt4 key购买 nike

我的库的用户将通过 getInstance<T>() 请求任何类的实例.

在所有类(class)中{T1,T2,T3,...,Tn}该用户在某个程序中询问(调用getInstance<T>()的样子),是否有一对(i,j)Ti源自 Tj ,我将只创建更大的一个,例如Ti .

这是一个例子。
假设用户代码要求我创建这些类:-

  • 物理
  • 刚性
  • 约束
  • 图形

    他们的继承如下:-

(图中用黄色标注了以上四个类。)

enter image description here

我的代码将创建覆盖整个树的最小 数量的类实例。
在这种情况下,最好的解决方案是 3 : Rigid , Constraint , Graphic .
粗略地说,三个箭头通过树中的所有类。

enter image description here

在这种情况下,将有 2 个 Physic 实例,但我不在乎。 (感谢 Christian Hackl)

更具体地说,getInstance<Physic>()可以返回其中任何一个。
基础类型可以是 Rigid*Constraint* - 都可以。

如果有多个最小解,其中任何一个都可以。

这是我的梦想:-

//..... some list to cache std::function .... ?
template<class T> T* getInstance(){
//return new T() ?
}
class B{};
class C{};
class D : public B{};
int main(){
//..... allow to insert some code here ...... (a little less preferable)
B* b=getInstance<B>(); //return B* (implicitly cast D*->B*)
C* c=getInstance<C>(); //return C*
D* d=getInstance<D>(); //return D*
assert( static_cast<D*>(b) == d );
delete d; delete c;
//no memory leak
}

怎么做?
这是最接近的问题:Create "custom typeid" for many types AND cache their sizeof()

我觉得这是可能的:我必须使用缓存类型:-

  • 没有捕获的 lambda/std::function -> 将其保存在列表中
  • 缓存函数调用std::is_base_of .
  • 然后,我必须以某种方式识别所有叶节点。
  • 必须实例化的类数量 = 叶节点数量。

然而,这远非一个具体的想法。

我想为我的图书馆和教育目的创建一个非常复杂的单例管理器。
我知道这不是一个好的做法,但我相信该解决方案会启发我在 C++ 领域。
以防万一它不是那么明显 - 这不是作业/面试。

最佳答案

你主要需要一个类型特征,给定一个类型和一个类型列表,从列表中返回一种顶级派生类型。

不是很优雅(我会尽量简化它)但是下面的代码应该给你一个例子

#include <cassert>
#include <iostream>
#include <type_traits>

struct core {};
struct physic : public core {};
struct rigid : public physic {};
struct constraint : public physic {};
struct graphic : public core {};

template <typename ... Ts>
struct contTypes
{ };

template <typename T0, typename T1>
struct isStrictBase
{ static constexpr bool value =
(false == std::is_same<T0, T1>::value)
&& (true == std::is_base_of<T0, T1>::value); };

template <bool, typename...>
struct chooseT;

template <typename, typename, typename>
struct getTopTypeH;

template <typename C0, typename T, typename T0, typename C1>
struct chooseT<true, C0, T, T0, C1>
{ using type = typename getTopTypeH<C0, T0, C0>::type; };

template <typename C0, typename T, typename T0, typename C1>
struct chooseT<false, C0, T, T0, C1>
{ using type = typename getTopTypeH<C0, T, C1>::type; };

template <typename, typename, typename>
struct getTopTypeH;

template <template <typename ...> class Ct, typename ... Ts0, typename T>
struct getTopTypeH<Ct<Ts0...>, T, Ct<>>
{ using type = T; };

template <template <typename ...> class Ct, typename ... Ts0,
typename T, typename T0, typename ... Ts>
struct getTopTypeH<Ct<Ts0...>, T, Ct<T0, Ts...>>
{
using type = typename chooseT<isStrictBase<T, T0>::value,
Ct<Ts0...>, T, T0, Ct<Ts...>>::type;
};

template <typename T, typename CT>
struct getTopType
{ using type = typename getTopTypeH<CT, T, CT>::type; };


template <typename T>
struct staticWrapper
{
static T * getPnt ()
{
static T st{};

return & st;
}
};

using cT = contTypes<core, physic, rigid, constraint, graphic>;

template <typename T>
T * getInstance ()
{ return staticWrapper<typename getTopType<T, cT>::type>::getPnt(); }

int main ()
{
auto p0 = getInstance<core>();
auto p1 = getInstance<physic>();
auto p2 = getInstance<rigid>();
auto p3 = getInstance<constraint>();
auto p4 = getInstance<graphic>();

assert( p0 == p1 );
assert( p0 == p2 );

std::cout << "assert passed" << std::endl;
}

关于c++ - 最小实例化类对象,查询getInstance<T>()时,基于继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43167392/

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