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

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

DECLARE @cmd varchar(4000)
DECLARE cmds CURSOR FOR
SELECT 'drop table [' + Table_Name + ']'
FROM INFORMATION_SCHEMA.TABLES
WHERE Table_Name LIKE 'prefix%'

OPEN cmds
WHILE 1 = 1
BEGIN
    FETCH cmds INTO @cmd
    IF @@fetch_status != 0 BREAK
    EXEC(@cmd)
END
CLOSE cmds;
DEALLOCATE cmds

Это более чисто, чем использование двухступенчатого подхода генерирует сценарий плюс выполнение. Но одно преимущество генерации скриптов состоит в том, что она дает Вам шанс рассмотреть полноту того, что будет выполненным, прежде чем она будет на самом деле выполнена.

я знаю, что, если бы я собирался сделать это против производственной базы данных, я был бы максимально осторожен.

Редактирование Пример кода зафиксирован.

19
задан 30 July 2009 в 15:34
поделиться

6 ответов

When you call a virtual method via a reference or a pointer you will always activate the virtual call mechanism that finds the most derived type.

Your best bet is to add an alternative function that is not virtual.

12
ответ дан 30 November 2019 в 05:06
поделиться

What you're trying to do unfortunately isn't possible. Pointer-to-member-functions are designed to maintain the virtualness of the function pointed-to.

2
ответ дан 30 November 2019 в 05:06
поделиться

. Ваша проблема в том, что указатель на функцию-член не совсем то же самое, что и простой указатель на функцию. На самом деле это не просто указатель, а значительно более сложная структура , детали которой меняются на уровне реализации компилятора. Когда вы вызываете его с помощью синтаксиса (this -> * fp) () , вы фактически вызываете его для исходного объекта, что вызывает отправку виртуальной функции.

Одна вещь, которая может сработать, - это привести его к типу, не являющемуся указателем метода. Он немного скрипит, но я думаю , что он должен работать. Вам все еще нужно передать Base * , но вы делаете это явно, и диспетчеризация виртуальной функции обходится:

typedef void BasePointer(Base*);

void callFunc()
{
    BasePointer fp = (BasePointer *)&Base::func;
    fp(this);
}

Обновление: Хорошо, нет, вы не можете сделать это таким образом. Это незаконно, и было бы небезопасно, если бы это было законно. Часто задаваемые вопросы по C ++ содержат дополнительную информацию об этом . Но знание этого не решает вашей проблемы. Проблема в том, что указатель на объект или указатель на член, если вы хотите вызвать Base :: func через указатель Base , объект, на который он указывает, должен ] также быть Базой . Если вы можете это организовать, то можете использовать указатель на функцию-член.

Вот еще одна мысль, не очень красивая, но по крайней мере работоспособный. Предоставьте функцию в Derived , не виртуальную, которая явно вызывает Base :: func . Вместо этого укажите на это. Он не будет масштабироваться, если вам нужно сделать это в общем случае множества различных вариантов func и callFunc , но он будет работать нормально для одного метода.

1
ответ дан 30 November 2019 в 05:06
поделиться

Is есть ли какая-то особая причина для этого через указатель функции?

Вы должны иметь возможность просто написать:

Base::func();

для вызова реализации базового класса.

0
ответ дан 30 November 2019 в 05:06
поделиться

В дополнение к тому, что говорит Quark, более общее замечание состоит в том, что вам следует использовать реализацию сигнала / слота, а не простой указатель на функцию. У Boost есть один, есть libsigc и множество других.

0
ответ дан 30 November 2019 в 05:06
поделиться

Что в этом плохого?

(Base(*this).*fp)();

Теперь, если вас это устраивает, возникает вопрос, почему вы вообще вообще используете указатель на функцию. Думаю, вам может помочь дополнительный контекст.

0
ответ дан 30 November 2019 в 05:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: