【问题标题】:c++ getting dynamic generic type of pointer?c ++获得动态泛型类型的指针?
【发布时间】:2010-01-07 23:56:36
【问题描述】:

标题可能有误导性,但我真的不知道如何命名。

假设我有以下结构

template <typename T>
struct SillyBase{
   void doFunnyStuff(vector<T> vec){
        dummyField = T();
        for(int i=0; i<10; i++)
            vec.push_back(dummyField++);
    }
    T dummyField;
 };

struct A : public SillyBase<char>{};

struct B : public SillyBase<float>{};

现在让我们进一步假设我有一个指针

ISillyBase* ptr;

它指向 SillyBase 的 DECENDANT 类(A 或 B)的对象 - 但是,我不知道是哪一个(我只知道它是 A 或 B);

我有什么方法可以调用 doFunnyStuff() 吗?

可能是这样的:

vector<dynamic_generic_type_of(ptr)> vec;
ptr->doFunnyStuff(vec);

谢谢!

【问题讨论】:

  • 投票关闭,因为不再相关,因为如何在ptr 上调用方法的问题是基于一个有缺陷的前提,即完全可以声明ptr .
  • 手头更大的问题是什么?
  • 您希望传入什么“类型”的向量?你想收集什么值?您是否希望将 char 和 floats 都存储在向量中?所以无论如何您都会将它们转换为一种类型...可能有一个简单的解决方案可以解决您的问题,但我们不知道您要解决的问题是什么

标签: c++ generics templates dynamic


【解决方案1】:

在您的示例中,您不能使用 SillyBase*,因为 SillyBase 被定义为

template <typename T> struct SillyBase {...}

所以你需要提供类型...

另一个问题是您将vector&lt;T&gt; 的副本传递给doFunnyStuff(),然后填充...这似乎不正确,因为当方法返回时您丢失了vec,它应该是引用@ 987654327@?

【讨论】:

  • 你可以在 ISillyBase 中有一个虚拟的 doFunnyStuff 但问题是它需要知道参数的类型......所以它不能是虚拟的......也许可以解释你想要实现的目标并且可能有更简单的解决方案。
【解决方案2】:

SillyBase *ptr; 甚至不应该编译。如果没有模板参数列表,SillyBase 就不是类型,因此尝试在需要类型的上下文中使用它应该会失败。

由于您一开始无法创建指针,因此对于如何取消引用它没有真正的答案。

【讨论】:

    【解决方案3】:

    这实际上是两个完全不同的类。在 100 年前的姨妈婚礼上遇到的班级中,无法通过名称来称呼功能。您必须重新设计解决方案以包含模板类的一些基类 喜欢

    class SillyBaseBase
    {
        public:
            void function doFunnyFunnyStuff(SillyBase<char> *)
            {
                SillyBase<char>::doFunnyStuff();
            }
    
            void function doFunnyFunnyStuff(SillyBase<float> *)
            {
                SillyBase<float>::doFunnyStuff();
            }
    
    }
    

    【讨论】:

      【解决方案4】:

      编辑:即使使用ISillyBase,也没有虚拟模板成员之类的东西,因此您将无法定义带有vector&lt;T&gt; 参数的模板。


      在您的示例中,没有像 SillyBase 这样的非模板类型,因此您不能声明 SillyBase* ptr;

      最后我并没有真正看到你想要实现的目标:/

      【讨论】:

        【解决方案5】:

        我认为您正在寻找的是内置的 dynamic_cast 模板功能。它动态确定数据结构的类型,如果不是实例化,则返回 null。语法是

        dynamic_cast<the_template_definition>(the_template_instantiation)
        

        一个重要的问题是模板类必须派生自一个通用的虚拟类。所以要做你想做的,你可以使用下面的代码:

        #include <stdio.h>
        class Top /* The parent class */ {
        public: 
        virtual ~Top() {}; // You need one base virtual function in the base class
        };
        
        template <typename T> class SillyBase : public Top {
           void doFunnyStuff(T dummyVar){
                dummyField  = dummyField + dummyVar;
            }
            T dummyField;
         };
        
        class A : public SillyBase<char>{};
        class B : public SillyBase<float>{};
        
        int main(){
           A a;
           Top *ptr = (Top*)(&a);
           if(dynamic_cast<A*>(ptr) != NULL)
              printf("ptr is of type A*\n");
           if(dynamic_cast<B*>(ptr) != NULL)
              printf("ptr is of type B*\n");
           return 0;
        }
        

        程序的输出将是:

        ptr is of type A*
        

        【讨论】:

          【解决方案6】:

          我可能会使用 dynamic_cast 关键字。尽管在声明向量时会遇到问题。它必须是 SillyBase 类型。这样做的问题是,这需要使用模板参数,这是未知且无法获得的。过去为了解决这个问题,我只是把vector放在base类型的Base类中,然后提供一个函数来修改它。继承的类将提供与基类中的向量同名的变量。继承基类函数的继承类有望填充正确的向量。我不知道这是个好主意还是坏主意,但这是我试图在我的项目中克服这个问题的方式。

          【讨论】:

            猜你喜欢
            • 2013-06-13
            • 2010-10-22
            • 2021-06-25
            • 2011-05-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-12
            • 1970-01-01
            相关资源
            最近更新 更多