Указатели на элементы функции - PullRequest
0 голосов
/ 09 марта 2012

У меня есть что-то похожее на

Base.h

#ifndef BASE_H
#define BASE_H

class Base
{
virtual Base* createNew() = 0;
}

#endif

D.h

#ifndef D_H
#define D_H

#include "Base.h"

class D : public Base
{
virtual Base* createNew();
}

#endif

D.cpp

#include "D.h"
Base* D:createNew()
{
return new D();
}

main.cpp

typedef Base* (Base::*FP)(void);

#include "D.h"

void create(FP pointer)
{
//empty for now
}

int main()
{
create(&D::createNew); //This doesnt work =s?

}

Я очень смущен, почему это не работает, кто-нибудь может дать мне совет о том, что я должен делать ????

Ps. Извините, если код не запускается, я поместил его, например, ради, просто чтобы показать вам, что я делал

Ответы [ 3 ]

2 голосов
/ 09 марта 2012

В вашем коде множество синтаксических проблем;

  • Base :: createNew () является частным и виртуальным.
  • Ни у одного объявления класса нет завершающего ;.
  • D: createNew () должно быть D :: createNew (). ...

Я думаю, что вы имеете в виду, что получение указателя на функцию-член и передача его методу не сработает.

Проблема в том, что вы берете метод, который можно вызывать только с D, и пытаетесь передать его в качестве указателя на функцию, которая может принять Base, который не обязательно является D. Обратное сработало бы (т. Е. Передав Base::createNew() функции, принимающей D::createNew(), поскольку Base::createNew() всегда существует в D, а не наоборот)

1 голос
/ 09 марта 2012

После исправления следующих тривиальных ошибок компилятора в вашем коде,

  1. Отсутствует ; после class тело
  2. Изменение D:createNew на D::createNew
  3. Создание D::createNew в public спецификаторе

Ваш код не компилируется в, create(&D::createNew). Потому что это не кабриолет. Сообщение об ошибке ясно:

error: cannot convert ‘Base* (D::*)()’ to ‘FP {aka Base* (Base::*)()}’ 

Редактировать : Одним из способов является использование template оценки, если вы решите сделать это во время компиляции.

template<typename ReturnType, typename Class>
void create(ReturnType (Class::*pointer)())
{
}

Назовите это как:

create<Base*, D>(&D::createNew);
1 голос
/ 09 марта 2012

попробовать:

 create(&Base::createNew);

В конце концов, create хочет указатель Base :: * на член, а не D :: *.

Я не думаю, что есть ковариация между линиями наследования для указателей на член; Указатель типа Base::* на элемент несовместим с указателем типа D::* на элемент.

Однако вы все равно можете вызывать виртуальную функцию D через указатель Base на член объекта D. A D действительно является своего рода Base, поэтому вы можете сделать dinst->*pmemb, где pmemb - это & ​​Base :: createNew`.

Также ...

Ваш D::createNew может вернуть D *. Эта «ковариация» в типе возврата виртуальной функции разрешена в C ++. Это все та же виртуальная функция, которая переопределяет функцию в Base, которая возвращает Base *. Когда вы звоните D::createNew напрямую, вы можете иногда получить указатель D *, чтобы вы могли работать с D.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...