就像标题所说,我正在寻找某种数据结构,这将允许我将任何类型的类存储到我当时需要的类中。例如:
Foo *foo = new Foo();
Bar *bar = new Bar();
someContainer.push_back( foo );
someContainer.push_back( bar );
someContainer.access( 0 )->doFooStuff();
someContainer.access( 1 )->doBarStuff();
理想情况下,正如我在那里展示的那样,它还允许我访问内容并使用它们的功能/等
我想要其中一个,因为我正在尝试创建一个“隐形”内存管理系统,只需要一个类来继承我的内存管理器类,一切都会自动运行。
以下是我希望代码看起来像的示例:
template< class T >
class MemoryManaged
{
MemoryManaged()
{
container.push_back( this );
}
void *operator new()
{
// new would probably be overloaded for reference counting etc.
}
void operator delete( void *object )
{
// delete would most definitely overloaded
}
T &operator=( T &other )
{
// = overloaded for reference counting and pointer management
}
static SomeContainer container;
}
class SomeClass : public MemoryManaged< SomeClass >
{
// some kind of stuff for the class to work
};
class AnotherClass : public MemoryManaged< AnotherClass >
{
// more stuff!
};
我希望我的代码有助于明确我想要做什么。如果有人知道某种已经构建的数据结构可以让我这样做,那就太棒了。否则,我目前正在构建某种使用模板化节点的链表类的抖动僵尸,以便将任何类型的类链接到任何其他类型的类。我仍然不知道我是如何让它继续工作的,而且我希望能够省去血液,汗水和眼泪(和头发),以便弄清楚如何使它发挥作用。
答案 0 :(得分:4)
为所有多种类型提供公共基类。让数据结构保持基类类型的指针。
答案 1 :(得分:3)
答案 2 :(得分:1)
模板专业化和双重调度的混合会有帮助吗?像这样:
class IContainable;
class Operation
{
public:
template<class ElementType> void Process(ElementType* pEl) {
// default is an unrecognized type, so do nothing
}
};
class IContainable
{
public:
virtual void OperateOn(Operation* pOperation) = 0;
};
class Foo : public IContainable
{
public:
int GetFooCount() { return 1; }
virtual void OperateOn(Operation* pOperation);
};
// specialization of the operation for Foo's
template <> void Operation::Process<Foo>(Foo* pFoo)
{
std::cout << pFoo->GetFooCount() << std::endl;
}
void Foo::OperateOn(Operation* pOperation)
{
pOperation->Process(this);
}
int main()
{
typedef std::vector<IContainable*> ElementVector;
ElementVector elements;
// configure elements;
Operation oper;
for(ElementVector::iterator it = elements.begin();
it != elements.end(); it++)
{
(*it)->OperateOn(&oper);
}
}
如果在容器上元素的操作的编译时不知道容器中的类型列表,或者它们是在未编译在一起的模块之间分布的,那么您可以改为使用dynamic_cast。您将使用名为“HandleFoo”的纯虚方法定义一个“IFooHandler”类,该方法采用foo指针。你将Operation :: Process虚拟化,让你的操作类派生自Operation和IFooHandler,并在HandleFoo()中实现操作。你的Foo :: OperateOn方法将是dynamic_cast(pOperation),如果结果是非null,它将在动态强制转换得到的IFooHandler指针上调用HandleFoo()。否则,您将调用通用的Operation :: Process,它将具有一些非类型特定的行为。
答案 3 :(得分:0)
使用std::vector<T*>
应该有效。实际上,将为MemoryManaged
的每个实例创建一个新类。这意味着MemoryManaged<Foo>
和MemoryManaged<Bar>
将是完全不同的类型。因此,静态成员container
对于这两个类并不常见。就好像你有以下两个类:
class MemoryManagedFoo
{
MemoryManagedFoo()
{
//Here, you know that 'this' is a Foo*
container.push_back(this); //ok, we add 'this' to a container of Foo*
}
static std::vector<Foo*> container;
};
class MemoryManagedBar
{
MemoryManagedBar()
{
//Here, you know that 'this' is a Bar*
container.push_back(this); //ok, we add 'this' to a container of Bar*
}
static std::vector<Bar*> container;
};
如您所见,两个实例不共享静态成员。
当然,此解决方案假定使用CRTP始终使用MemoryManaged
,如您在问题中所述。换句话说,这段代码将起作用:
class Foo : public MemoryManaged<Foo> { };
但不是这一个:
class Foo : public MemoryManaged<Bar>
{
// Here, 'container' is a 'vector<Bar*>' and 'this' is a Foo * --> problem
};