C++获取指针的动态通用类型?

3

标题可能会误导人,但我真的不知道该怎么命名。

假设我有以下结构体:

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的一个后代类(A或B)的实例,然而我并不知道具体是哪一个(只知道它可能是A或B)。

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

也许可以像这样:

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

thanks!


投票关闭,理由为“不再相关”,因为如何在ptr上调用方法的问题基于错误的前提,即根本无法声明ptr - Rob Kennedy
手头的大问题是什么? - GManNickG
你希望传入什么类型的向量?你想要收集什么值?你期望在向量中存储char和float类型吗?如果是的话,你需要将它们转换为一种类型... 可能有一个简单的解决方案来解决你的问题,但我们不知道你试图解决什么问题。 - stefanB
6个回答

1
在你的例子中,你不能有 SillyBase*,因为 SillyBase 已经被定义了。
template <typename T> struct SillyBase {...}

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

另一个问题是,你将vector<T>的副本传递到doFunnyStuff()中,然后你填充它...这似乎不对,因为当方法返回时,你会失去你的vec,它应该是引用vector<T>&吗?


在ISillyBase中,你可以有一个虚拟的doFunnyStuff函数,但问题是它需要知道参数的类型...所以它不能是虚拟的...也许解释一下你想要实现什么,可能会有更简单的解决方案。 - stefanB

0

这实际上是两个完全不同的类。在它们的姑婆婚礼上相遇100年后,没有办法按名称调用类中的函数。您必须重新设计解决方案,以包括一些基类用于您的模板类,例如

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

        void function doFunnyFunnyStuff(SillyBase<float> *)
        {
            SillyBase<float>::doFunnyStuff();
        }

}

0

我认为你要查找的是内置的 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*

0

编辑:即使使用ISillyBase,也没有虚拟模板成员这样的东西,因此您将无法定义一个带有vector<T>参数的模板。


在你的例子中,没有非模板类型叫做 SillyBase,因此你不能声明 SillyBase* ptr;

最终我并不真正明白你想要实现什么 :/


0

SillyBase *ptr; 这段代码甚至不应该编译通过。没有模板参数列表,SillyBase 不是一个类型,因此试图在需要类型的上下文中使用它应该会失败。

由于你无法创建指针,所以如何取消引用它也没有真正的答案。


0

我可能会选择使用dynamic_cast关键字。虽然在声明向量时会遇到问题。它必须是SillyBase类型的。这个问题在于,这需要使用模板参数,这些参数是未知且无法获取的。为了解决这个问题,过去我只是将向量放在类型为base的基类中,并提供一个函数来修改它。继承类将提供与向量在基类中相同名称的变量。继承基类函数的继承类将希望填充正确的向量。我不知道这是好主意还是坏主意,但这是我在项目中尝试解决这个问题的方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接