C++ Программирование в среде С++ Builder 5

_Declspec


Применение этого ключевого слова не ограничено визуальным программированием, однако также участвует в поддержке кода VCL.

Общее применение _declspec

Выражение вида _declspec (аргумент) является модификатором, который может применяться к функциям или переменным. Аргументы dllexport, dilimport и thread формируют модификаторы, соответствующие обычным export, _import и _thread. Разница между ними заключается в том, что обычные модификаторы должны всегда непосредственно предшествовать имени объявляемой переменной или функции, в то время как модификаторы _declspec можно помещать в любом месте объявления:

void _declspec(dllexport) f(void);// Верно.

_declspec(dllexport) void f(void);// Верно.

_export void f(void) // Ошибка: должно быть

// void export.

Другими аргументами _declspec общего применения являются:

  • naked: Применяется к определению функции. Подавляет генерацию кода пролога/эпилога вызова, позволяя программисту написать свой собственный код, используя встроенный ассемблер.
    • noreturn: Сообщает компилятору, что функция не возвращает управления вызывающей программе. Обычно, когда компилятор обнаруживает, что при некоторых условиях функция, объявленная с типом возвращаемого значения, ничего не возвращает, он выдает предупреждение. Однако если эта ситуация связана с вызовом другой функции, не возвращающей управления, то, объявив последнюю с модификатором _declspec (noreturn), можно подавить такое предупреждение. Вот пример:

    _declspec(noreturn) void finish(){



    ...

    throw "No return";

    }

    int RetInt(){

    if(....)

    return 1;

    else

    finish(); // Без noreturn генерировалось бы

    // предупреждение.

  • nothrew: Соответствует спецификации исключения без аргументов. Следующие объявления эквивалентны:
  • __declspec(nothrow) void f();

    void f() throw();

  • novtable: Применяется к классам, для которых никогда не будет создаваться представителей. В большинстве случаев этот модификатор подавляет генерирование vtaDie и, соответственно, кода всех функции,на которые она ссылается.

  • property: Позволяет реализовать в классе не статические “виртуальные элементы данных”, нечто вроде свойств. Синтаксис:


  • _declspec(property(get = get-функция,

    put = put-функция)) объявление_ элемента;

    Одна из спецификаций функций доступа может быть опущена. Компилятор транслирует обращения к “элементу данных” в вызовы функций доступа. Возможно также объявление “массива” с одним или несколькими “индексами”:

    declspec(property(get=GetVal, put=PutVal)) int vArr[];

    Число индексов в обращении к виртуальному массиву должно соответствовать числу параметров у функций доступа. (У простой виртуальной переменной get-функция не имеет ни одного, а put-функция имеет один параметр — присваиваемое значение.) Индексы не обязательно должны быть целыми, они могут быть, например, строками.

  • selectany: Применяется к глобальным переменным. В ANSI C/C++ принята концепция пробного определения (tentative definition). Если встречается объявление глобальной переменной без модификаторов класса хранения и без инициализации, оно рассматривается как пробное определение. Если тот же идентификатор появляется позднее в другом файле, предыдущее пробное определение считается объявлением external.


  • Однако инициализация глобальной переменной должна производиться только в одном месте. Если, например, глобальная переменная объявляется и инициализируется в заголовочном файле, подключаемом несколькими файлами проекта, при компоновке возникнет ошибка. Спецификация seiectany решает эту проблему:

    _declspec(selectany) int gint = 10;

    // Может появляться в

    // нескольких файлах проекта.

    selectany не может применяться к неинициализируемым переменным и переменным, недоступным за пределами текущего файла (т. е. глобальным статическим, например, глобальным константам C++ без спецификатора external).

  • uuid: Присоединяет GUID к объявляемому классу. Применяется только к СОМ-классам. Синтаксис:


  • _Declspec (uuid("GUID_COM-объекта") )

    объявление/определение класса



    Применение _declspec с VCL



    Перечисленные ниже аргументы _declspec, служащие для поддержки VCL, редко применяются непосредственно. Они используются в макросах, определяемых файлом vcl\sysmac.h.



  • delphiclass: Может применяться для объявления классов, производных от TObject. Для классов, объявленных с этим аргументом _declspec, обеспечивается совместимость с VCL no RTTI, поведению конструкторов/деструкторов и обработке исключений. Накладываются также некоторые ограничения: класс не может быть сложным производным, его представители могут создаваться только динамически, он обязан иметь деструктор и для него не генерируются автоматически конструктор копии и операция присваивания по умолчанию.


  • delphireturn: Только для внутреннего использования VCL в C++Builder. Служит для поддержки встроенных типов ObjectPascal, для которых не существует эквивалентов в C++. Применяется в реализациях классов C++Builder Currency, AnsiString, Variant, TDateTime и Set.


  • dynamic: Служит для объявления динамических функций. По своему поведению они не отличаются от виртуальных, но реализуются по-другому. Они включаются в виртуальную таблицу только того класса, который их определяет. Тем самым экономится память, но падает эффективность, так как иногда приходится производить поиск в виртуальных таблицах, возможно, нескольких базовых классов. Аргумент может применяться только к функциям классов, производных от TObject.


  • hidesbase: В языке Object Pascal виртуальные функции базового класса могут появляться в производном как функции, не имеющие никакого отношения к одноименным функциям базового класса (это имеет место, если у производной функции не указан спецификатор override). Применение hidesbase к объявлению функции производного класса моделирует эту семантику Object Pascal.


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


  • pascalimplementation: Показывает, что код класса реализован на Object Pascal. Применяется в заголовочных файлах .hpp, моделирующих интерфейс Pascal-классов VCL.



  • Содержание раздела