C++ 如何给结构一个“a”;虚拟的;typedef?

C++ 如何给结构一个“a”;虚拟的;typedef?,c++,C++,我有一个structBaseStorage,它存储各种运行时数据,还有一个structBaseStatic,它保存BaseStorage(或派生的)typedef和“static”数据,这些数据不会被更改,可以从structHolder的多个实例中读取Holder有一个指向其中一个的指针,一个const BaseStatic*用于访问该只读共享数据,一个BaseStorage*作为其个人信息存储。BaseStatic中的“静态”数据仍在运行时填充(从文件读取);它不是常数 这里的想法是,Base

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

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

因此,我需要一个派生的
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();
}
template Holder&builder(const T*base)//接收BaseStatic
{
持有者&持有者=。。。;
//添加到列表等中
holder.base=底座;
holder.storage=new T::Base();
}
然而,这将导致编译器为一件非常琐碎的事情(访问单个类型!)生成许多模板化函数。此外,我的T::Base构造函数永远不能有参数(除非所有结构都有相同的参数!)。我相信这在其他方面也很糟糕

是否有任何方法可以存储一个可以从
BaseStatic
虚拟访问的类型,而无需使用模板?一定有更好的办法


有各种各样的限制因素导致了我的这种设置,所以如果它很难看,我很抱歉。

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

构造函数问题的一个解决方案是使用C++11可变模板参数:

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;
}
模板
持有者生成器(const T*base,Args…Args)//接收BaseStatic
{
持有人;
//添加到列表等中
holder.base=底座;
holder.storage=新类型名T::storage(args…);
报税表持有人;
}
请注意,要使其正常工作,派生存储类型必须与
BaseStorage
一起使用私有继承,否则
storage
typedef将变得不明确


现在,根据项目的范围,这可能会扩展为许多函数,但请记住--“暂时不要优化。”

我使用了Raymond Chen的评论,并在
BaseStatic
中创建了此方法:

Storage* CreateStorage() const {return new Storage();}
并在
DerivedStatic
中用以下内容覆盖它:

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

BaseStorage
和/或
BaseStatic
中是否有虚拟接口,或者您只是使用继承作为编写的替代方式?(我看不出虚拟析构函数是我问的原因)。您可以向
BaseStatic
添加一个名为
virtualbasestorage*CreateStorage(){return new BaseStorage;}
的虚拟方法。
DerivedStatic
将覆盖它以读取
BaseStorage*DerivedStatic::CreateStorage(){return new DerivedStorage;}