2009-03-12 2 views
1

Это, вероятно, обычное избыточное программирование. Я заметил DECLSPEC_NOVTABLE (__declspec (novtable)) на кучу интерфейсов, определенных в заголовках:DECLSPEC_NOVTABLE на чистых виртуальных классах?

struct DECLSPEC_NOVTABLE IStuff : public IObject 
{ 
    virtual method1() = 0; 
    virtual method2() = 0; 
}; 

MSDN article на этом __declspec расширенного атрибута говорит, что добавление этого парня удалит конструкта и desctructor виртуальные таблицы записи и, таким образом, приводит к «значительное сокращение размера кода» (потому что vtable полностью удаляется).

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

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

Так что я думаю, чтобы подвести итог:

  • ли компилятор вычистить виртуальные таблицы независимо для чисто виртуальных интерфейсов, или я что-то пропустил основополагающее здесь?
  • О чем говорится в статье MSDN?

ответ

2

Компилятор разбирает это ссылаться только на виртуальные таблицы, которая была бы при строительстве класса. Поэтому компоновщик может оптимизировать его, поскольку в коде больше нет ссылки.

Также, кстати, у меня появилась привычка объявлять пустой конструктор как protected, а также с помощью ключевого слова расширения Microsoft abstract, чтобы избежать нарушения доступа во время выполнения. Таким образом, компилятор поймает проблему во время компиляции (поскольку только базовый класс может создать интерфейс через защищенный конструктор). Разумеется, производный класс будет заполнять vtable во время его строительства.

+0

Почему вы не избегаете нарушения доступа во время работы? Нехорошо знать, когда кто-то создает виртуальный класс? Все еще немного нечеткое на этом;). – RedBlueThing

+0

Вместо этого он принимает ошибку во время компиляции. Ответ отредактирован. – zildjohn01

1

Это немного ручная работа для немого компилятора/компоновщика. Компилятор не должен вставлять ссылки на эту таблицу vtable, так как совершенно очевидно, что эта таблица vtable не нужна. Компилятор также мог бы отметить ссылку таким образом, чтобы компоновщик мог исключить vtable, но это, конечно, сложнее.

Смежные вопросы