繁体   English   中英

调用由空指针引用的对象的函数

[英]Call a function of an object referenced by a void Pointer

我有一个这样的功能:

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

编译器说,取消引用运算符的左边必须是指向类/结构/联合/泛型的指针(从德语翻译,不确定其措辞)。

这个想法是,我想打电话给something不管obj的功能是什么传给something 确保它具有此功能。 我该如何实现?

- 编辑 -

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

对于传递给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*作为参数表明设计 您到底想达到什么目的?

C ++不允许这样做(有充分的理由:即使您可以确保对象始终具有功能,C ++也不能,并且由于您会出错,所以C ++不信任您是有道理的)。

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

另外,如果在编译时知道此处使用的是哪种类型,则适当的实现将使用模板:

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

无论您做什么, void* 都不适合。 在C ++中,很少有合法用例。

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

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

在每个结构和类的标头中编写: public ,然后编写接口名称也很重要!

您需要使用以下功能实现纯虚拟基类:

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
   }
}

而且比使用动态转换从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   

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

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

调用看起来像:

doSth( &function );

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM