2

我有一个BaseStorage存储各种运行时数据的结构,以及一个BaseStatic保存BaseStorage(或派生的)typedef 和“静态”数据的结构,这些数据不会被更改并从 struct 的多个实例中读取HolderHolder有一个指向其中一个的指针,一个const BaseStatic*用于访问该只读共享数据的指针,以及一个BaseStorage*作为其个人信息存储的指针。中的“静态”数据BaseStatic仍然在运行时填充(从文件中读取);它不是恒定的!

这里的想法是BaseStatic具有一组特定的只读数据和函数,这些数据和函数将在许多Holder实例之间 1:N 共享。每个Holder还将具有特定于其实例的运行时信息,这些信息需要与BaseStatic派生类型匹配。这就是BaseStorage派生的东西所做的,它包含一个BaseStatic类型需要的特定运行时信息。 Holder本身也存储数据,功能在所有Holders中都是一样的;它不是惰性容器。

所以我需要一个BaseStorage与每个派生配对的派生BaseStatic。会有很多这样的派生对。

struct BaseStorage
{
 int something[2];
};

struct BaseStatic
{
 typedef BaseStorage Storage;

 //members and stuff
};


struct DerivedStorage : public BaseStorage
{
 std::string somethingelse;
};

struct DerivedStatic : public BaseStatic
{
 typedef DerivedStorage Storage;

 //other things
};


struct Holder
{
 const BaseStatic* base;
 BaseStorage* storage;
};

我有一个构建器函数可以做一些事情,其中​​包括填充存储。我能想到的唯一方法是使用模板,如下所示:

template<typename T> Holder& builder(const T* base) //receives a BaseStatic
{
 Holder& holder = ...;

 //add to a list, etc

 holder.base = base;
 holder.storage = new T::Base();
}

但是,这将导致编译器为一件非常琐碎的事情(访问单一类型!)而生成许多模板化函数。此外,我的 T::Base 构造函数永远不能有参数(除非所有结构都具有相同的结构!)。我相信这在其他方面也很糟糕。

有什么方法可以存储可以在BaseStatic不使用模板的情况下虚拟访问的类型?一定有更好的办法。

有各种限制导致我进行此设置,所以如果它很难看,我深表歉意。

4

2 回答 2

0

我使用了 Raymond Chen 的评论并在以下位置创建了这个方法BaseStatic

Storage* CreateStorage() const {return new Storage();}

并用以下方法覆盖它DerivedStatic

Storage* CreateStorage() const {return new Storage();}
于 2013-11-07T17:16:42.730 回答
0

模板并不像你想象的那么糟糕。任何多态解决方案都可能需要某种 RTTI 使用,这将需要比较和间接分支——可能比一堆模板化函数更贵或更便宜,并且根据您的要求,这可能是坏的、好的或更可能是毫无意义的。请记住,每个唯一的模板参数集将实例化唯一一个模板,因此T在您的情况下每个基数只有一个。

构造函数问题的一种解决方案是使用 C++11 Variadic Template args:

template<typename T, typename ...Args> 
Holder builder(const T* base, Args ...args) //receives a BaseStatic
{
  Holder holder;

  //add to a list, etc

  holder.base = base;
  holder.storage = new typename T::Storage(args...);
  return holder;
}

请注意,要使其正常工作,派生存储类型必须使用私有继承 with BaseStorage,否则Storagetypedef 会变得不明确。

现在,根据您的项目范围,这可能会爆发出很多功能,但请记住——“不要优化”。

于 2013-11-06T18:33:31.670 回答