void *指针(不是模板)的C ++替代方法 [英] C++ alternatives to void* pointers (that isn't templates)

查看:330
本文介绍了void *指针(不是模板)的C ++替代方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎我对C ++有一个基本的误解:<

It looks like I had a fundamental misunderstanding about C++ :<

我喜欢多态容器解决方案.谢谢您,让我引起注意:)

I like the polymorphic container solution. Thank you SO, for bringing that to my attention :)

因此,我们需要创建一个相对通用的容器类型对象.它还碰巧封装了一些与业务相关的逻辑.但是,我们实际上需要在此容器中存储任意数据-从原始数据类型到复杂类的所有内容.

So, we have a need to create a relatively generic container type object. It also happens to encapsulate some business related logic. However, we need to store essentially arbitrary data in this container - everything from primitive data types to complex classes.

因此,人们会立即跳到模板类的想法并完成它.但是,我注意到C ++多态性和模板不能很好地配合使用.鉴于我们需要处理一些复杂的逻辑,所以我宁愿坚持使用模板或多态性,而不是尝试通过使二者同时使用来对抗C ++.

Thus, one would immediately jump to the idea of a template class and be done with it. However, I have noticed C++ polymorphism and templates do not play well together. Being that there is some complex logic that we are going to have to work, I would rather just stick with either templates OR polymorphism, and not try to fight C++ by making it do both.

最后,鉴于我想做一个或另一个,我宁愿使用多态.我发现代表该容器包含可比较类型"这样的约束要容易得多-像Java.

Finally, given that I want to do one or the other, I would prefer polymorphism. I find it much easier to represent constraints like "this container contains Comparable types" - a la java.

将我带到一个问题:最抽象的说,我想我可以拥有一个容器"纯虚拟接口,该接口类似于"push(void * data)和pop(void * data)"(记录下来,我实际上并不是在尝试实现堆栈.)

Bringing me to the topic of question: At the most abstract, I imagine that I could have a "Container" pure virtual interface that has something akin to "push(void* data) and pop(void* data)" (for the record, I am not actually trying to implement a stack).

但是,我不太喜欢顶层的void *,更不用说每次我想对具体容器可以使用的数据类型添加约束时签名都会改变的情况.

However, I don't really like void* at the top level, not to mention the signature is going to change every time I want to add a constraint to the type of data a concrete container can work with.

总结:我们有相对复杂的容器,这些容器具有各种检索元素的方式.我们希望能够改变对可以放入容器的元素的约束.元素应该与多种容器一起工作(只要它们满足特定容器的约束).

Summarizing: We have relatively complex containers that have various ways to retrieve elements. We want to be able to vary the constraints on the elements that can go into the containers. Elements should work with multiple kinds of containers (so long as they meet the constraints of that particular container).

我还应该提到容器本身需要是多态的.这是我不想使用模板化C ++的主要原因.

I should also mention that the containers themselves need to be polymorphic. That is my primary reason for not wanting to use templated C++.

所以-我应该放弃对Java类型接口的热爱并选择模板吗?我应该使用void *并静态转换所有内容吗?还是应该使用不声明任何内容的空类定义"Element",并将其用作"Element"层次结构中的顶级类?

So - should I drop my love for Java type interfaces and go with templates? Should I use void* and statically cast everything? Or should I go with an empty class definition "Element" that declares nothing and use that as my top level class in the "Element" hierarchy?

我之所以喜欢堆栈溢出,原因之一是许多响应提供了一些我什至没有想到的其他方法的有趣见解.因此,在此先感谢您的见解和评论.

One of the reasons why I love stack overflow is that many of the responses provide some interesting insight on other approaches that I hadn't not have even considered. So thank you in advance for your insights and comments.

推荐答案

您是否没有包含元素的根Container类:

Can you not have a root Container class that contains elements:

template <typename T>
class Container
{
public: 

   // You'll likely want to use shared_ptr<T> instead.
   virtual void push(T *element) = 0;
   virtual T *pop() = 0;
   virtual void InvokeSomeMethodOnAllItems() = 0;
};

template <typename T>
class List : public Container<T>
{
    iterator begin();
    iterator end();
public:
    virtual void push(T *element) {...}
    virtual T* pop() { ... }
    virtual void InvokeSomeMethodOnAllItems() 
    {
       for(iterator currItem = begin(); currItem != end(); ++currItem)
       {
           T* item = *currItem;
           item->SomeMethod();
       }
    }
};

这些容器随后可以多态传递:

These containers can then be passed around polymorphically:

class Item
{
public:
   virtual void SomeMethod() = 0;
};

class ConcreteItem
{
public:
    virtual void SomeMethod() 
    {
        // Do something
    }
};  

void AddItemToContainer(Container<Item> &container, Item *item)
{
   container.push(item);
}

...

List<Item> listInstance;
AddItemToContainer(listInstance, new ConcreteItem());
listInstance.InvokeSomeMethodOnAllItems();

这以一种类型安全的通用方式为您提供了Container接口.

This gives you the Container interface in a type-safe generic way.

如果要对可包含的元素类型添加约束,则可以执行以下操作:

If you want to add constraints to the type of elements that can be contained, you can do something like this:

class Item
{
public:
  virtual void SomeMethod() = 0;
  typedef int CanBeContainedInList;
};

template <typename T>
class List : public Container<T>
{
   typedef typename T::CanBeContainedInList ListGuard;
   // ... as before
};

这篇关于void *指针(不是模板)的C ++替代方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆