Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Преобразование неполиморфных типов static_cast
Формат операции: static_cast <type-id> (exp)
Преобразует exp в тип type-id на основе исключительно тех типов, которые присутствуют в выражении. На этапе выполнения никакой контроль типов не производится. Операция static_cast может быть использована для преобразования указателя на базовый класс в указатель на производный класс. Такие преобразования не всегда безопасны. Преимущественно эта операция используется для преобразования таких числовых данных, как перечисления, в целочисленный тип или целых в вещественные. Операция static_cast менее безопасна по сравнению с dynamic_cast, поскольку static_cast не контролируется на этапе выполнения, в то время как при выполнении dynamic_cast это делается. В то время как dynamic_cast вызовет ошибку при преобразовании неоднозначных указателей, операция static_cast выполнится без ошибки, что опасно. Пример: // static_cast_Operator.cpp // compile with: /LD class B {}; class D : public B {};
void f(B* pb, D* pd) { D* pd2 = static_cast<D*>(pb); // опасно, так как pb может указывать именно на B B* pb2 = static_cast<B*>(pd); // безопасное преобразование }
В противоположность dynamic_cast, при выполнении static_cast не выполняется проверка указателя на этапе выполнения. Это значит, что, к примеру, вызов функции класса D, а не В, вызовет ошибку “access violation”. Еще один пример: // static_cast_Operator_2.cpp // compile with: /LD /GR class B { public: virtual void Test(){} }; class D : public B {};
void f(B* pb) { D* pd1 = dynamic_cast<D*>(pb); D* pd2 = static_cast<D*>(pb); }
Если pb действительно указывает на объект типа D, то pd1 и pd2 будут иметь одно и то же значение. Они также будут иметь одинаковое значение, если pb == 0. Если же pb указывает на объект типа B, а не на завершенный класс D, то dynamic_cast вернет значение 0. Напротив, static_cast зависит от убежденности программиста в том, что pb указывает на объект типа D и просто вернет указатель на предполагаемый объект типа D. Следовательно, static_cast может выполнить такое неявное преобразование, при котором результат будет неопределенным. И тогда програмист должен убедиться в том, что результат преобразования static_cast корректный и безопасный. Такое поведение операции свойственно не только применительно к классам. Например, static_cast может быть использована для преобразования int в char. Однако, результирующий тип char может не иметь достаточного количества битов для сохранения значения int. Пример для иллюстрации: // static_cast_Operator_3.cpp // compile with: /LD /GR typedef unsigned char BYTE;
void f() { char ch; int i = 65; float f = 2.5; double dbl; ch = static_cast<char>(i); // int to char dbl = static_cast<double>(f); // float to double i = static_cast<BYTE>(ch); }
Операция static_cast может однозначно конвертировать значение интегрального типа в перечисление. Если значение интегрального типа не входит в интервал перечисления, результирующее значение перечисления будет неопределенным. Операция static_cast конвертирует нулевой указатель в нулевой указаетль результирующего типа. Любое значение может быть конвертировано к типу void с помощью static_cast. Результирующий тип void может включать атрибуты const, volatile и __unaligned. Операция static_cast не может отменить действие атрибутов const, volatile или __unaligned. См. операцию const_cast.
Преобразование reinterpret_cast Преобразует любой указатель в указатель другого типа: reinterpret_cast <type_id > (exp)
Эта операция позволяет конвертировать любой интегральный тип в любой указатель и наоборот. The reinterpret_cast operator also allows any integral type to be converted into any pointer type and vice versa. Неправильное использование операции reinterpret_cast может легко стать небезопасным. Операция reinterpret_cast может быть использована для таких преобразований, как char* в int* или One_class * в Unrelated_class*, которые по своей сути небезопасны. Результат преобразования reinterpret_cast не может быть безопасно использован, если обратное преобразование не позволяет вернуться к первоначальному значению. Другие преобразования, в лучшем случае, являются непереносимыми. Операция reinterpret_cast не может отменить действие атрибутов const, volatile или __unaligned. Операция reinterpret_cast преобразует нулевой указатель в нулевой указатель результирующего типа. Примером практического использования операции может служить хэш-функция, которая отображает значение в индекс таким образом, что два разных значения редко получают один и тот же индекс, например: // expre_reinterpret_cast_Operator.cpp // compile with: /EHsc // генерирует и возвращает хэш-код по адресу unsigned short Hash( void *p ) { unsigned int val = reinterpret_cast<unsigned int>( p ); return ( unsigned short )( val ^ (val >> 16)); }
int main() { int a[20]; for ( int i = 0; i < 20; i++ ) cout << Hash( a + i ) << endl; }
В приведенной программе операция reinterpret_cast позволяет трактовать указатель как интегральный тип. Полученный результат затем сдвигается вправо и к нему применяется операция XOR для получения уникального, с высокой степенью вероятности, индекса. Полученный индекс затем усекается и возвращается функцией.
Соглашения об именах
Имена типов. В Windows SDK и MFC используются такие имена типов:
В MFC используются также такие типы:
Имена переменных и функций. Фирма Microsoft использует сама и рекомендует другим разработчикам руководствоваться соглашениями об именах, известных также как «венгерская» нотация. Для функций используются имена, построенные из глаголов и существительных, причем первые буквы этих слов рекомендуется делать заглавными. Для имен переменных Microsoft предлагает более сложную систему, предусматривающую указание в качестве префикса типа данных. Префикс рекомендуется составлять из строчных букв, а собственно имя начинать с заглавной буквы. Типы префиксов представлены в нижеследующей таблице. Откровенно говоря, использование префиксов, обозначающих тип данных, спорно и не всегда адекватно. Большинство Windows-программистов прибегают к такой системе именования, но Вы в своих программах можете поступать по своему усмотрению.
Другие гласные и негласные соглашения. В библиотеке MFC и приложениях, разрабатываемых с ее помощью, принято имена классов начинать с большой буквы C: CString, CDialog и т.п. Имена констант, перечислений и макросов в библиотеках принято, как правило, задавать заглавными буквами: NULL или IDCANCEL (значения заданы с помощью директивы препроцессора define), enum { IDD = IDD_ABOUTBOX }, TRACE (макрос). Имена член данных классов принято начинать с префикса m_, например, m_pDocument (член указатель на документ).
Соглашения об именовании библиотек MFC DLL и LIB. (См. также в MSDN указатель «Conventions») Имена библиотек MFC (.dll и .lib) назначаются в соответствии с приведенными ниже соглашениями, что помогает сориентироваться в том, какие библиотеки и для какой цели используются в каждом конкретном случае. Разделяемые библиотеки (shared MFC DLL в отличие от статически связываемых Static-Link Regular DLL) именуются в соответствии с шаблоном MFC[O|D|N]x0[U][D].DLL где x – номер версии MFC.
Библиотеки импорта .lib (import libraries), которые используются для компоновки приложений или DLL-расширений (extension DLLs), имеют те же имена, но расширение .lib вместо .dll.
Именование разделяемых библиотек MFC DLL
Примечания к таблице. Release – окончательная версия, Debug – отладочная. Библиотеки DLL, содержащие элементы управления ActiveX, обычно имеют тип .ocx. Библиотеки импорта MFCSx0[D].LIB используются в связке с библиотеками MFC DLL. Если Вы динамически компонуете разделяемые библиотеки MFC DLL с приложениями или DLL-расширениями, Вы должны распространять вместе с приложением библиотеки MFCx0.DLL или Unicode-версии MFCx0U.DLL. Retail-версии библиотек MFCx0.DLL и MFCx0U.DLL содержат поддержку технологии Active, баз данных и сетей в одной единственной DLL, в то время как Debug-версии используют разные библиотеки для этих функциональных областей. . Если Вы статически компонуете свою DLL с MFC, Вы должны компоновать ее с одной из статических библиотек MFC. Эти библиотеки именуются в соответствии с шаблоном [N|U]AFXCW[D].LIB, описанным в следующей таблице.
Соглашения об именах статически компонуемых библиотек (Static-Link Regular DLL)
Примечание. В версиях MFC до 4-ой использовались специальные варианты библиотек с именами в формате [N|U]AFXDW[D].LIB. Эти библиотеки сейчас не используются и вместо них надо применять версии, приведенные в таблице. Полный список библиотек Visual C++, которые могут распространяться с приложением, приведен в файле REDISTRB.WRI на компакт-диске с Visual C++. В MSDN сведения о библиотеках, которые необходимо распространять вместе с приложением, можно найти в разделе «Categories of Redistributable Files».
Пространства имен
Пространство имен представляет собой механизм логического группирования объявлений, которые можно объединить по какому-либо критерию общности. Пространства имен являются одним из средств решения проблемы конфликта имен, которая имеет место быть в большой программе. Объявление пространства имен (namespace declaration): Namespace MyNameSpace { int iNumber=0; int Func(float); void Hello(){cout<<”Hello!”<<endl;} } |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2018-04-12; просмотров: 419. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |