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