Виртуальный метод объявлен в классе, но не определен

Моя цель — найти все места, где вызывается какая-то функция.
Поэтому я определяю из него новый класс и делаю функцию недоступной.
Но я не определяю метод, и я получил ошибку ссылки.

Вот код:

A.hpp:

#ifndef _A_HPP
#define _A_HPP
class _declspec(dllexport) A
{
public:
virtual void f1();
};
class _declspec(dllexport) B: public A
{
private:
void f1();
};
#endif

a.cpp:

#include "A.hpp"void A::f1(){}

program.cpp:

#include "A.hpp"
int main(void )
{
A a;
a.f1();
return 0;
}

B::f1() никогда не вызывается, но у меня все еще есть ошибка связи.
Но если вы удалите _declspec(dllexport) это строит хорошо.

0

Решение

На функцию ссылается таблица виртуальных функций для класса А.

http://en.wikipedia.org/wiki/Virtual_method_table

Вы не можете иметь виртуальные функции (кроме чисто виртуальных функций), которые не определены. Они должны быть определены так, чтобы была определена виртуальная таблица.

Делать функцию приватной также бесполезно, как просто вызов (&A) .f1 () вызовет B :: f1 ().


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

struct Foo { virtual void foo(); };
struct Goo : public Foo { void foo() {} };

int main()
{
Goo f;
return 0;
}

приводит к ошибке компоновщика (с использованием GCC),

undefined reference to `typeinfo for Foo'

что, как и ожидалось. Что происходит в вашем случае с удаленным экспортом, так это то, что MSVC, вероятно, обманывает. Он видит весь класс и все его применения и не генерирует виртуальную таблицу. Это оптимизирует это. Он знает, что вы не используете эту виртуальную таблицу во внешнем коде, поэтому он не беспокоится об этом.

Я также не получаю ошибки, если компилирую с включенной оптимизацией по той же причине.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector