Вызов функции объекта, на который ссылается пустой указатель - PullRequest
1 голос
/ 16 февраля 2012

У меня есть такая функция:

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

Компилятор говорит, что слева от оператора разыменования должен быть указатель на класс / struct / union / generic (перевод с немецкого не уверен в формулировке).

Идея состоит в том, что я хочу вызвать функцию something объекта obj независимо от того, что передано something. Гарантируется, что он имеет эту функцию. Как мне этого добиться?

- EDIT -

Я начал работать над существующим программным обеспечением, которое имеет> 100 классов для типов данных. В одной части кода есть большой оператор switch, который в зависимости от идентификатора создает экземпляр одного из этих классов и вызывает для него функцию Set. Теперь я хочу сделать несколько из этих вызовов параллельными, и из-за этого я хочу привести вызов -> Set () к отдельной функции, которую я затем могу вызвать в новом потоке. К сожалению, нет базового класса, и я не могу изменить слишком много в «большой картине». Каков наилучший способ сделать это?

Ответы [ 5 ]

1 голос
/ 16 февраля 2012

C ++ не допускает этого (по уважительным причинам: даже если вы можете гарантировать, что у объекта всегда есть функция, C ++ не может, и, поскольку вы можете делать ошибки, C ++ оправдывает ваше недоверие).* Правильный способ сделать это - иметь общий базовый класс, который определил этот метод для всех типов, которые вы хотите использовать здесь, а затем использовать этот общий базовый класс в качестве аргумента этой функции.

В качестве альтернативыесли во время компиляции известно, какой тип используется здесь, то соответствующая реализация использует шаблоны:

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

Что бы вы ни делали, void* является не соответствующим.В C ++ есть очень редкие законные варианты использования.

1 голос
/ 16 февраля 2012

Вам нужен базовый класс или интерфейс для всего, что передается в 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* в качестве параметра предполагает неисправный дизайн .Что именно вы пытаетесь достичь?

0 голосов
/ 02 мая 2015

Просто определите интерфейс, который перечисляет все функции всех объектов, на которые вы хотите ссылаться указателем, но тип этого указателя не должен быть пустым, а вместо этого имя этого интерфейса.

Затем вы сможете вызывать каждую функцию каждого объекта, который вам нужен, с помощью этого указателя, но убедитесь, что все структуры и классы объектов реализуют все функции интерфейса!

Это также важно написать: public, а затем имя интерфейса в заголовке каждой структуры и класса!

0 голосов
/ 16 февраля 2012

Метод doSth может принимать указатель на функцию в качестве параметра.

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

Звонок будет выглядеть так:

doSth( &function );

При передаче указателей функций между различными классами вы должны создать typedef для каждого указателя функции и использовать квалификаторы для каждого идентификатора функции.

0 голосов
/ 16 февраля 2012

Вам необходимо реализовать чистый виртуальный базовый класс с помощью этой функции:

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

А затем используйте динмическое приведение, чтобы получить Базу * из пустоты *

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   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...