Каково лучшее объяснение ключевого слова экспорта в C++ 0x стандарт?

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

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

23
задан Laurent Couvidou 14 April 2012 в 01:28
поделиться

7 ответов

Хотя стандартный C ++ не предъявляет таких требований, некоторые компиляторы требуют, чтобы все шаблоны функций были доступны в каждой единице перевода, в которой они используются. Фактически, для этих компиляторов тела функции шаблона должны быть доступны в файле заголовка. Повторюсь: это означает, что эти компиляторы не позволяют определять их в файлах без заголовков, таких как файлы .cpp. Чтобы уточнить, в C ++ ese это означает, что this:

// ORIGINAL version of xyz.h
template <typename T>
struct xyz
 {
    xyz();
    ~xyz();
 };

НЕ будет удовлетворен этими определениями ctor и dtors:

// ORIGINAL version of xyz.cpp
#include "xyz.h"

template <typename T>
xyz<T>::xyz() {}

template <typename T>
xyz<T>::~xyz() {}

, потому что его использование:

// main.cpp
#include "xyz.h"

int main()
 {
    xyz<int> xyzint;

    return 0;
 }

приведет к ошибке. Например, с Comeau C ++ вы получите:

 C: \ export> como xyz.cpp main.cpp
С ++ 'ing xyz.cpp ...
Comeau C / C ++ 4.3.4.1 (29 мая 2004 г., 23:08:11) для MS_WINDOWS_x86
Авторское право 1988-2004 Comeau Computing. Все права защищены.
РЕЖИМ: нестрогие предупреждения microsoft C ++
С ++ в main.cpp ...
Comeau C / C ++ 4.3.4.1 (29 мая 2004 г., 23:08:11) для MS_WINDOWS_x86
Авторское право 1988-2004 Comeau Computing. Все права защищены.
РЕЖИМ: нестрогие предупреждения microsoft C ++
main.obj: ошибка LNK2001: неразрешенный внешний символ xyz  :: ~ xyz  () [с T1 = int]
главный.obj: ошибка LNK2019: неразрешенный внешний символ xyz  :: xyz  () [с T1 = int], на который имеется ссылка в функции _main
aout.exe: фатальная ошибка LNK1120: 2 нерешенных внешних фактора

потому что в xyz.cpp не используются ни ctor, ни dtor, следовательно, нет необходимости создавать экземпляры оттуда. Хорошо это или плохо, но так работают шаблоны.

Один из способов обойти это - явно запросить создание экземпляра xyz в этом примере xyz . Попыткой грубой силы это может быть добавлено в xyz.cpp, добавив эту строку в конце:

template xyz<int>;

, которая запрашивает создание (всех) xyz экземпляров. Это вроде как не в том месте, поскольку это означает, что каждый раз, когда вызывается новый тип xyz, необходимо изменять файл реализации xyz.cpp. Менее навязчивый способ избежать этого файла - создать другой:

// xyztir.cpp
#include "xyz.cpp" // .cpp file!!!, not .h file!!

template xyz<int>;

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

Другой способ подойти к этому - #include "xyz.cpp" в конец xyz.h:

// xyz.h

// ... previous content of xyz.h ...

#include "xyz.cpp"

Вы, конечно, можете буквально перенести (вырезать и вставить) содержимое xyz.cpp до конца xyz.h, таким образом избавляясь от xyz.cpp; это вопрос организации файлов, и, в конце концов, результаты предварительной обработки будут одинаковыми, поскольку тела ctor и dtor будут в заголовке и, следовательно, будут включены в любой запрос компиляции, поскольку для этого будет использоваться соответствующий заголовок.В любом случае у этого есть побочный эффект: теперь каждый шаблон находится в вашем файле заголовка. Это может замедлить компиляцию и привести к раздуванию кода. Один из способов приблизиться к последнему - объявить рассматриваемые функции, в данном случае ctor и dtor, как встроенные, поэтому вам потребуется изменить xyz.cpp в текущем примере.

Кроме того, некоторые компиляторы также требуют, чтобы некоторые функции были определены внутри класса, а не за его пределами, поэтому в случае этих компиляторов потребуется дополнительная настройка описанной выше настройки. Обратите внимание, что это проблема компилятора, а не стандартного C ++, поэтому не все компиляторы требуют этого. Например, Comeau C ++ этого не делает и не должен. Посетите http://www.comeaucomputing.com/4.0/docs/userman/ati.html для получения подробной информации о нашей текущей настройке. Короче говоря, Comeau C ++ поддерживает множество моделей, в том числе ту, которая приближается к намерениям ключевого слова export (как расширение), а также даже поддерживает сам экспорт.

Наконец, обратите внимание, что ключевое слово C ++ export призвано облегчить исходный вопрос. Однако в настоящее время Comeau C ++ - единственный компилятор, который публикуется для поддержки экспорта. См. http://www.comeaucomputing.com/4.0/docs/userman/export.html и http://www.comeaucomputing.com/4.3.0/minor/win95+/43stuff. txt для получения дополнительных сведений. Будем надеяться, что по мере того, как другие компиляторы достигнут соответствия стандарту C ++, эта ситуация изменится. В приведенном выше примере использование экспорта означает возврат к исходному коду, который вызвал ошибки компоновщика, и внесение изменений: объявление шаблона в xyz.h с ключевым словом export:

// xyz.h

export
// ... ORIGINAL contents of xyz.h ...

ctor и dtor в xyz.cpp будут экспортированы просто благодаря #includeing xyz.h, что он уже делает. Итак, в этом случае вам не нужен xyztir.cpp,ни запрос на создание экземпляра в конце xyz.cpp, и вам не нужно вручную вносить ctor или dtor в xyz.h. С помощью командной строки, показанной ранее, возможно, что компилятор сделает все за вас автоматически.

25
ответ дан 29 November 2019 в 01:33
поделиться

См. этот объяснение его использования

, Довольно много компиляторов не поддерживают его или потому что это является слишком новым или в случае gcc - потому что они не одобряют.

Это сообщение описывает стандартную поддержку многих компиляторов. поддержка Visual Studio нового C / стандарты C++?

7
ответ дан Bloodgain 29 November 2019 в 01:33
поделиться

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

Comeau представил его сначала, приблизительно 5 лет назад IIRC. Это работало вполне хорошо над первой бета-версией, которую я получил. Даже тестовые сценарии как A< 2> использование B< 2> использование A< 1> с помощью B< 1> с помощью A< 0>, обработанный, если шаблоны A и B прибыли из различного TU's. Несомненно, компоновщик неоднократно вызывал компилятор, но все поиски имени работали хорошо. Инстанцирование A< 1> найденный именами от A.cpp, которые были невидимы в B.cpp.

5
ответ дан JK. 29 November 2019 в 01:33
поделиться

Помещать его просто:

export позволяет Вам разделить объявление (т.е. заголовок) из определения (т.е. код), когда Вы пишете свои шаблонные классы. Если export не поддерживается Вашим компилятором тогда, необходимо положить объявление и определение на одно место.

4
ответ дан Rodyland 29 November 2019 в 01:33
поделиться

Единственными компиляторами, которые поддерживают экспортируемые шаблоны в данный момент (насколько я знаю) является Comeau, тот, который шел с Разработчиком Borland C++ X, но не текущим Разработчиком C++ и Intel (по крайней мере, неофициально, если не официально, не уверенный).

2
ответ дан KTC 29 November 2019 в 01:33
поделиться
Другие вопросы по тегам:

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