调用void指针引用的对象的函数

时间:2012-02-16 09:30:50

标签: c++ pointers

我有这样的功能:

void something(void *obj)
{
    obj->Set();
}

编译器说dereference运算符的左边必须是一个指向类/ struct / union / generic的指针(从德语翻译不确定措辞)。

我的想法是,无论传递给something的是什么,我都想调用obj的something函数。确保它具有此功能。我怎样才能做到这一点?

- 编辑 -

我开始研究一个类似于>的现有软件。 100个数据类型的类。在代码的一部分中有一个大的switch语句,它根据id创建这些类之一的实例并调用该函数的Set函数。现在我想要并行执行多个这些调用,因此我想将 - > Set()调用带到一个单独的函数,然后我可以在一个新线程中调用它。可悲的是,没有基础类,我不能在“大局”中改变太多。这样做的最佳方式是什么?

5 个答案:

答案 0 :(得分:1)

对于传递给doSth的任何内容,您需要一个基类或接口:

class Base
{
public:
   virtual void something() = 0; //override this in derived classes
}

doSth(Base* obj)
{
   obj->something();
}

您还可以将void*转换回原始类型:

doSth(void* obj)
{
   ((Base*)obj)->something();
}

但是传递void*作为参数表明错误设计。你究竟想要实现什么目标?

答案 1 :(得分:1)

C ++不允许这样做(出于好的理由:即使你可以确保对象总是有一个函数,C ++也不能,并且因为你可以犯错,所以C ++不信任你)。

执行此操作的正确方法是使用一个公共基类,为要在此处使用的所有类型定义此方法,然后使用此公共基类作为此函数的参数。

或者,如果在编译时知道这里使用了哪种类型,那么相应的实现使用模板:

template <typename T>
void f(T const& obj) {
    obj.something();
}

无论您做什么,void* 都不适合。在C ++中有非常罕见的合法用例。

答案 2 :(得分:0)

您需要使用此函数实现纯虚拟Base类:

class Base
{
   public:
   virtual ~Base(){}
   virtual void somefunction()=0;
}

class Derived1: public Base
{
   public:
   void somefunction()
   {
     //do something
   }
}

class Derived2: public Base
{
   public:
   void somefunction()
   {
     //do something
   }
}

而且使用dynmic cast从void *

获得Base *
doSth(void *obj)
{
  Base *bobj=dynamic_cast<Base*>(obj);
  if ( bobj )
    bobj->somefunction();
}

或者更简单:

doSth(Base *obj)
{
  obj->somefunction();
}

用法如下:

Base *p1 = new Derived1(); 
Base *p2 = new Derived2();
doSth(p1); // cals somefunction in Derived1 class
doSth(p2); // cals somefunction in Derived2 class   

答案 3 :(得分:0)

doSth方法可以将函数指针作为参数。

doSth( (*someFunc)() ) {
 obj->*someFunc();
}

电话会是:

doSth( &function );

在不同类之间传递函数指针时,应为每个函数指针创建一个typedef,并为每个函数标识符使用限定符。

答案 4 :(得分:0)

只需定义一个接口,列出要通过指针引用的所有对象的所有函数,但该指针的类型不应该为void,而是该接口的名称。

然后你可以通过这个指针调用你想要的每个对象的每个函数,但是要确保对象的所有结构和类都实现了接口的所有功能!

在每个结构和类的标题中编写"options": { "cwd": "${workspaceRoot}/mySubDir" }, 然后编写接口的名称也很重要!