<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.itkazan.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Kazan Dev Alliance</title><link>http://www.itkazan.com/blogs/</link><description>Казанское Сообщество Разработчиков Программного Обеспечения</description><dc:language>en-US</dc:language><generator>CommunityServer 2007 SP2 (Build: 20611.960)</generator><item><title>требуется помощь сообщества: бесконтрольно размножаются vsmdi файлы</title><link>http://www.itkazan.com/blogs/raimon/archive/2008/08/18/vsmdi.aspx</link><pubDate>Mon, 18 Aug 2008 10:22:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1999</guid><dc:creator>Raimon</dc:creator><slash:comments>2</slash:comments><description>кто-нибудь может дать внятное объяснение бесконтрольно плодящимся vsmdi файлам? ...(&lt;a href="http://www.itkazan.com/blogs/raimon/archive/2008/08/18/vsmdi.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1999" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/raimon/archive/tags/visual+studio/default.aspx">visual studio</category><category domain="http://www.itkazan.com/blogs/raimon/archive/tags/question/default.aspx">question</category></item><item><title>Указание пути для создания логов в log4net</title><link>http://www.itkazan.com/blogs/raimon/archive/2008/08/15/log4net_2D00_configuration_2D00_tip.aspx</link><pubDate>Fri, 15 Aug 2008 16:01:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1998</guid><dc:creator>Raimon</dc:creator><slash:comments>2</slash:comments><description>пара слов о конфигурировании log4net...(&lt;a href="http://www.itkazan.com/blogs/raimon/archive/2008/08/15/log4net_2D00_configuration_2D00_tip.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1998" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/raimon/archive/tags/.NET/default.aspx">.NET</category><category domain="http://www.itkazan.com/blogs/raimon/archive/tags/tips/default.aspx">tips</category></item><item><title>const_cast и устранение дублирования кода</title><link>http://www.itkazan.com/blogs/alexdemche/archive/2008/08/06/const-cast.aspx</link><pubDate>Wed, 06 Aug 2008 10:22:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1987</guid><dc:creator>Alexandr Demchenko</dc:creator><slash:comments>0</slash:comments><description>&lt;span style="font-weight:bold;"&gt;const_cast&lt;/span&gt; &lt;br /&gt;

&lt;p&gt;С точки зрения С++ если имеется некоторый тип T (без квалификаторов const или volatile), то тип const T (volatile T, const volatile T) является отдельным типом. Однако, во многих случаях можно использовать один вместо другого.&lt;/p&gt;

&lt;p&gt;Например:&lt;/p&gt;

&lt;pre&gt;&lt;span style="font-weight:bold;"&gt;const&lt;/span&gt; T f()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="font-weight:bold;"&gt;return&lt;/span&gt; T(); &lt;span&gt;//&lt;/span&gt; &lt;span&gt;T&lt;/span&gt; &lt;span&gt;не&lt;/span&gt; &lt;span&gt;является&lt;/span&gt; &lt;span&gt;const&lt;/span&gt; &lt;span&gt;T&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;С другой стороны такая взаимозаменяемость не всегда возможна, например:&lt;/p&gt;

&lt;pre&gt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt; t = &lt;span style="color:blue;"&gt;12&lt;/span&gt;;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;const&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp; const_ref_t = t;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp; ref_t = const_ref_t; &lt;span&gt;//&lt;/span&gt; &lt;span&gt;ошибка,&lt;/span&gt; &lt;span&gt;присваивание&lt;/span&gt; &lt;span&gt;не&lt;/span&gt; &lt;span&gt;возможно&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Эти правила о том, когда можно и нельзя неявно приводить, направлены на соблюдение безопасности. Понятно, что безопасно преобразовывать неконстантный объект к константному, но, вообще говоря, не наоборот. Поэтому первый пример успешно компилируется, а второй - нет.&lt;/p&gt;

&lt;p&gt;Однако, конечно, программист может взять на себя ответственность, и явно осуществить небезопасное преобразование из константного объекта в неконстантный.&lt;/p&gt;

&lt;p&gt;Например, понятно, что во втором примере const_ref_t можно без опасения преобразовать к int&amp;amp;, поскольку объект, на который ссылается const_ref_t реально не является константой. В С++, как известно, за снятие и установление константности (или volatile) на объект отвечает оператор приведения const_cast. const_cast выглядит как шаблонная функция, параметром шаблона которой является тип, к которому осуществляется преобразование, а обычным параметром - объект, который нужно преобразовать. Вот как можно было бы использовать const_cast во втором примере:&lt;/p&gt;

&lt;pre&gt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt; t = &lt;span style="color:blue;"&gt;12&lt;/span&gt;;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;const&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp; const_ref_t = t;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp; ref_t = &lt;span style="font-weight:bold;"&gt;const_cast&lt;/span&gt;&amp;lt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp;&amp;gt;(const_ref_t); &lt;span&gt;//осуществляется&lt;/span&gt; &lt;span&gt;явное&lt;/span&gt; &lt;span&gt;преобразование&lt;br /&gt;&lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt;из&lt;/span&gt; &lt;span&gt;const&lt;/span&gt; &lt;span&gt;T&amp;amp;&lt;/span&gt; &lt;span&gt;к&lt;/span&gt; &lt;span&gt;T&amp;amp;.&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;В результате такого преобразования, ref_t так же, как и const_ref_t ссылается на t. Поэтому ref_t++ влечет увеличение t на единицу. &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Несколько модифицируем пример, объявив t константой.&lt;/p&gt;

&lt;pre&gt;&lt;span style="font-weight:bold;"&gt;const&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;int&lt;/span&gt; t = &lt;span style="color:blue;"&gt;12&lt;/span&gt;;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;const&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp; const_ref_t = t;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp; ref_t = &lt;span style="font-weight:bold;"&gt;const_cast&lt;/span&gt;&amp;lt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp;&amp;gt;(const_ref_t); &lt;span&gt;//Снятие&lt;/span&gt; &lt;span&gt;константности,&lt;/span&gt; &lt;span&gt;ОК&lt;/span&gt;&lt;br /&gt;ref_t++; &lt;span&gt;//Попытка&lt;/span&gt; &lt;span&gt;изменить&lt;/span&gt; &lt;span&gt;константу&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;неопределенное&lt;/span&gt; &lt;span&gt;поведение.&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Приведение типов здесь пройдет успешно, но попытка модифицировать по полученной ссылке значение влечет неопределенное поведение, так как это по ссылке хранится дейтствительно константа.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;При этом поскольку поведение в указанной ситуации не определено, исполнив такой код, Вы не обязательно получите ошибку времени выполнения или какое-нибудь диагностическое сообщение. Я, например, откомпилировав этот код на компиляторе MS VS 2005 и запустив его, получил, что после ref_t++ значение константы не изменилось. При этом, конечно, поведение от запуска к запуску может меняться. В силу указанных причин такую ошибку сложно отловить в процессе отладки.&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Использование const_cast для устранения дублирования кода.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;Представим, что мы решили написать простую обертку для встроенных массивов C++:&lt;/p&gt;

&lt;pre&gt;&lt;span style="font-weight:bold;"&gt;class&lt;/span&gt; Array&lt;br /&gt;{&lt;br /&gt;    &lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;* pArray;&lt;br /&gt;    &lt;span style="font-weight:bold;"&gt;int&lt;/span&gt; length;&lt;br /&gt;   &lt;br /&gt;&lt;span style="font-weight:bold;"&gt;public&lt;/span&gt;:&lt;br /&gt;    &lt;span&gt;//Methods&lt;/span&gt;&lt;br /&gt;};&lt;/pre&gt;

&lt;p&gt;Теперь нам хочется удобно обращаться к элементам массива - читать и изменять их. Поэтому мы решаем определить оператор []:&lt;/p&gt;

&lt;pre&gt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp; operator[](&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt; index)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="font-weight:bold;"&gt;if&lt;/span&gt; ( (index &amp;lt; &lt;span style="color:blue;"&gt;0&lt;/span&gt;) || index &amp;gt;= length)&lt;br /&gt;            &lt;span style="font-weight:bold;"&gt;throw&lt;/span&gt; std::exception(&lt;span style="font-weight:bold;"&gt;&amp;quot;Incorrect&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;index&amp;quot;&lt;/span&gt;);&lt;br /&gt;        &lt;span style="font-weight:bold;"&gt;return&lt;/span&gt; pArray;&lt;br /&gt;    }&lt;/pre&gt;

&lt;p&gt;Теперь, имея такой оператор мы можем читать и записывать элементы:&lt;/p&gt;

&lt;pre&gt;Array arr(&lt;span style="color:blue;"&gt;12&lt;/span&gt;);&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt; val_3 = arr[&lt;span style="color:blue;"&gt;3&lt;/span&gt;]; &lt;span&gt;//Читаем&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;arr[&lt;span style="color:blue;"&gt;3&lt;/span&gt;] = &lt;span style="color:blue;"&gt;14&lt;/span&gt;; &lt;span&gt;//Изменяем&lt;/span&gt; &lt;/pre&gt;

&lt;p&gt;Но, что если мы хотим переменную arr объявить константой? В таком случае все еще логично позволять пользователю читать элементы, а записывать - конечно, нет. В случае нашего же метода, поскольку он объявлен неконстатным, он не сможет быть вызван даже для чтения:&lt;/p&gt;

&lt;pre&gt;&lt;span style="font-weight:bold;"&gt;const&lt;/span&gt; Array arr(&lt;span style="color:blue;"&gt;12&lt;/span&gt;);&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt; val_3 = arr[&lt;span style="color:blue;"&gt;3&lt;/span&gt;]; &lt;span&gt;//Ошибка&lt;/span&gt; &lt;span&gt;компиляции,&lt;/span&gt; &lt;span&gt;&lt;br /&gt;//вызов&lt;/span&gt; &lt;span&gt;неконстатного&lt;/span&gt; &lt;span&gt;метода&lt;/span&gt; &lt;span&gt;для&lt;/span&gt; &lt;span&gt;константого&lt;/span&gt; &lt;span&gt;объекта.&lt;/span&gt; &lt;/pre&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
Для того, чтобы позволить читать элементы констатного массива, мы вынуждены создать константный аналог оператора []:
&lt;pre&gt;&lt;span style="font-weight:bold;"&gt;const&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp; operator[](&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt; index) &lt;span style="font-weight:bold;"&gt;const&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="font-weight:bold;"&gt;if&lt;/span&gt; ( (index &amp;lt; &lt;span style="color:blue;"&gt;0&lt;/span&gt;) || index &amp;gt;= length)&lt;br /&gt;            &lt;span style="font-weight:bold;"&gt;throw&lt;/span&gt; std::exception(&lt;span style="font-weight:bold;"&gt;&amp;quot;Incorrect&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;index&amp;quot;&lt;/span&gt;);&lt;br /&gt;        &lt;span style="font-weight:bold;"&gt;return&lt;/span&gt; pArray;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;Теперь все нормально. Если оператор [] вызывается для констатного объекта, то вызовется его константный вариант. При этом, попытка изменить элемент константного массива вызовет ошибку компиляции, так как будет попытка присвоить значение по константной ссылке.&lt;/p&gt;

&lt;pre&gt;&lt;span style="font-weight:bold;"&gt;const&lt;/span&gt; Array arr(&lt;span style="color:blue;"&gt;12&lt;/span&gt;);&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt; val_3 = arr[&lt;span style="color:blue;"&gt;3&lt;/span&gt;]; &lt;span&gt;//ОК,&lt;/span&gt; &lt;span&gt;вызывается&lt;/span&gt; &lt;span&gt;operator[]&lt;/span&gt; &lt;span&gt;const&lt;/span&gt;&lt;br /&gt;arr[&lt;span style="color:blue;"&gt;3&lt;/span&gt;] = &lt;span style="color:blue;"&gt;12&lt;/span&gt;; &lt;span&gt;//Ошибка&lt;/span&gt; &lt;span&gt;компиляции&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;вызывается&lt;/span&gt; &lt;span&gt;operator[]&lt;/span&gt; &lt;span&gt;const,&lt;/span&gt; &lt;span&gt;&lt;br /&gt;//но&lt;/span&gt; &lt;span&gt;по&lt;/span&gt; &lt;span&gt;константной&lt;/span&gt; &lt;span&gt;ссылке,&lt;/span&gt; &lt;span&gt;которую&lt;/span&gt; &lt;span&gt;он&lt;/span&gt; &lt;span&gt;возвращает&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;нельзя&lt;/span&gt; &lt;span&gt;менять&lt;/span&gt; &lt;span&gt;объект&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;Итак, окончательно имеем класс:&lt;/p&gt;

&lt;pre&gt;&lt;span style="font-weight:bold;"&gt;class&lt;/span&gt; Array&lt;br /&gt;{&lt;br /&gt;    &lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;* pArray;&lt;br /&gt;    &lt;span style="font-weight:bold;"&gt;int&lt;/span&gt; length;&lt;br /&gt;   &lt;br /&gt;&lt;span style="font-weight:bold;"&gt;public&lt;/span&gt;:&lt;br /&gt;    &lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp; operator[](&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt; index)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="font-weight:bold;"&gt;if&lt;/span&gt; ( (index &amp;lt; &lt;span style="color:blue;"&gt;0&lt;/span&gt;) || index &amp;gt;= length)&lt;br /&gt;            &lt;span style="font-weight:bold;"&gt;throw&lt;/span&gt; std::exception(&lt;span style="font-weight:bold;"&gt;&amp;quot;Incorrect&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;index&amp;quot;&lt;/span&gt;);&lt;br /&gt;        &lt;span style="font-weight:bold;"&gt;return&lt;/span&gt; pArray[index];&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="font-weight:bold;"&gt;const&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp; operator[](&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt; index) &lt;span style="font-weight:bold;"&gt;const&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="font-weight:bold;"&gt;if&lt;/span&gt; ( (index &amp;lt; &lt;span style="color:blue;"&gt;0&lt;/span&gt;) || index &amp;gt;= length)&lt;br /&gt;            &lt;span style="font-weight:bold;"&gt;throw&lt;/span&gt; std::exception(&lt;span style="font-weight:bold;"&gt;&amp;quot;Incorrect&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;index&amp;quot;&lt;/span&gt;);&lt;br /&gt;        &lt;span style="font-weight:bold;"&gt;return&lt;/span&gt; pArray[index];&lt;br /&gt;    }&lt;br /&gt;}; &lt;/pre&gt;

&lt;p&gt;&amp;nbsp;Здесь мы конечно замечаем известный &lt;a href="http://insidecpp.ru/antipatterns/copy_and_paste/" target="_blank"&gt;антипаттерн Copy and Paste&lt;/a&gt;.&amp;nbsp; Одну и ту же функциональность нам пришлось просто скопировать и вставить в константный аналога оператора []. Если здесь это не так много - всего 3 строчки, то, конечно, в реальных ситуациях, этот общий код может быть гораздо больше.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;Конечно, можно попробовать избавиться от Copy and Paste, например, просто вызвав из константного метода неконстантный. Так конечно сделать нельзя, поскольку неконстантный метод может изменять объект и компилятор это понимает. Однако, никакого вреда не будет, если мы из неконстантного метода вызовем констатный.&lt;/p&gt;

&lt;p&gt;Код мог бы выглядеть примерно так:&lt;/p&gt;

&lt;pre&gt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp; operator[](&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt; index)&lt;br /&gt; {&lt;br /&gt;    &lt;span style="font-weight:bold;"&gt;const&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp; ref_elem = &lt;span&gt;/*&lt;/span&gt; &lt;span&gt;call&lt;/span&gt; &lt;span&gt;operator&lt;/span&gt; &lt;span&gt;[]&lt;/span&gt; &lt;span&gt;const&lt;/span&gt; &lt;span&gt;*/&lt;/span&gt;&lt;br /&gt;    &lt;span style="font-weight:bold;"&gt;return&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;const_cast&lt;/span&gt;&amp;lt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp;&amp;gt;(ref_elem); &lt;span&gt;//Безопасно,&lt;/span&gt; &lt;span&gt;&lt;br /&gt;    //так&lt;/span&gt; &lt;span&gt;как&lt;/span&gt; &lt;span&gt;реально&lt;/span&gt; &lt;span&gt;объект&lt;/span&gt; &lt;span&gt;не&lt;/span&gt; &lt;span&gt;является&lt;/span&gt; &lt;span&gt;константой&lt;/span&gt;&lt;br /&gt; }&lt;/pre&gt;

&lt;p&gt;Перед возвратом из функции нужно преобразовать полученную константную ссылку к неконстантной, поскольку мы планируем, что посредством неконстантного оператора [] пользователь может захотеть изменить элемент массива.&lt;/p&gt;

&lt;p&gt;Вопрос здесь в том как вызвать именно константный метод. Прямого способа указать компилятору, что мы хотим вызвать именно этот метод, нет. Однако, он сам это сделает, если увидит, что вызов [] применен к константному объекту. В таком случае, самое время вспомнить о const_cast и &amp;quot;навесить&amp;quot; константность на this. Итоговый код будет таким:&lt;/p&gt;

&lt;pre&gt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp; operator[](&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt; index)&lt;br /&gt;{&lt;br /&gt;   &lt;span style="font-weight:bold;"&gt;return&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;const_cast&lt;/span&gt;&amp;lt;&lt;span style="font-weight:bold;"&gt;int&lt;/span&gt;&amp;amp;&amp;gt;( &lt;span style="font-weight:bold;"&gt;const_cast&lt;/span&gt;&amp;lt;&lt;span style="font-weight:bold;"&gt;const&lt;/span&gt; Array*&amp;gt;(&lt;span style="font-weight:bold;"&gt;this&lt;/span&gt;)&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;gt; operator[index] );&lt;br /&gt;}&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;Дополнительные материалы:&lt;/pre&gt;&lt;pre&gt;&lt;a href="http://www.informit.com/guides/content.aspx?g=cplusplus&amp;amp;seqNum=134" target="_blank"&gt;Операторы преобразования С++&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/6ke686zh.aspx" target="_blank"&gt;Константные функции-члены&lt;/a&gt;&lt;br /&gt;&lt;a href="http://insidecpp.ru/antipatterns/" target="_blank"&gt;Антипаттерны&lt;br /&gt;&lt;/a&gt;Книга Скотта Мэйерса &amp;quot;Эффективное использование С++. 55 верных советов улучшить структуру и код &lt;br /&gt;ваших программ&amp;quot;. Правило 3 (Как избежать дублирования в константных и неконстантных функциях-членах)&lt;br /&gt;&lt;/pre&gt;
&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1987" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/alexdemche/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://www.itkazan.com/blogs/alexdemche/archive/tags/C_2B002B00_+const+member+functions/default.aspx">C++ const member functions</category><category domain="http://www.itkazan.com/blogs/alexdemche/archive/tags/C_2B002B00_+cast+operators/default.aspx">C++ cast operators</category><category domain="http://www.itkazan.com/blogs/alexdemche/archive/tags/patterns/default.aspx">patterns</category><category domain="http://www.itkazan.com/blogs/alexdemche/archive/tags/const_5F00_cast/default.aspx">const_cast</category><category domain="http://www.itkazan.com/blogs/alexdemche/archive/tags/antipatterns/default.aspx">antipatterns</category></item><item><title>catch (Exception e)  =&gt;  e ==null</title><link>http://www.itkazan.com/blogs/raimon/archive/2008/08/01/catched_2D00_exception_2D00_is_2D00_null.aspx</link><pubDate>Fri, 01 Aug 2008 16:09:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1971</guid><dc:creator>Raimon</dc:creator><slash:comments>0</slash:comments><description>история о том, что не все инварианты инвариантны :)...(&lt;a href="http://www.itkazan.com/blogs/raimon/archive/2008/08/01/catched_2D00_exception_2D00_is_2D00_null.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1971" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/raimon/archive/tags/bugs/default.aspx">bugs</category><category domain="http://www.itkazan.com/blogs/raimon/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Questions from C++ examine</title><link>http://www.itkazan.com/blogs/alexdemche/archive/2008/08/01/hello.aspx</link><pubDate>Fri, 01 Aug 2008 09:09:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1974</guid><dc:creator>Alexandr Demchenko</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;В зимнем семестре мне довелось в КГУ читать спец. курс по С++. Предполагалось, что студенты ранее могли не изучать C или С++.&lt;/p&gt;
&lt;p&gt;В зимнем семестре удалось рассмотреть базовые конструкции языка и классы. Шаблоны были перенесены на весенний семестр. Также одна лекция была посвящена макросам.&lt;/p&gt;
&lt;p&gt;Программу зимнего семестра можно &lt;a class="" href="http://itkazan.com/files/folders/alexdemche/entry1972.aspx"&gt;скачать тут&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Экзамен делилился на 2 части. Первая и главная часть - практическая. Нужно было реализовать класс и протестировать его. Это задание было в двух вариантах. Первым вариантом было реализовать класс DynamicArray - массив, при необходимости расширяющий свои размеры (похожий на std::vector). Вторым вариантом - реализовать класс String (строка). Практическое задание было достаточно подробно описано. Было небольшое preview, в котором описывались проблемы, которые разрабатываемый класс должен решить, был приведен интерфейс класса и, наконец, были приведены некоторые инварианты, которым класс должен удовлетворять. Последнее, в частности, должно было снизить вероятность возникновения спорных вопросов, когда, к примеру, я считаю, что некоторая функциональность работает неверно, а студент считает, что верно.&lt;/p&gt;
&lt;p&gt;Практическое задание (C++) - вариант 1 (&lt;a class="" href="http://itkazan.com/files/folders/alexdemche/entry1976.aspx"&gt;PDF скачать&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Практическое задание (C++) - вариант 2 (PDF скачать)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Второй маленькой частью экзамена были простенькие (где-то даже забавные)&amp;nbsp;вопросы по С++, которые не требуют большого исследования. Размещаю эти вопросы и жду ответов в комментах ;-)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div&gt;&lt;font face="SFRM1200"&gt;
&lt;p align="left"&gt;Пусть задан некоторый встроенный тип Т. Всегда ли результат sizeof(T) зависит от реализации?&lt;/p&gt;&lt;/font&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;font face="SFRM1200"&gt;
&lt;p align="left"&gt;Не используя инструкций выбора напишите функцию Round, которая принимает аргумент типа float и возвращает целое, являющееся результатом округления аргумента. Гарантируется, что аргумент&lt;br /&gt;неотрицателен.&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;Правила округления обычные: если дробная часть меньше 0.5, то выбирается наибольшее целое, не превышающее аргумента. В противном случае -&amp;nbsp; наименьшее целое, которое не меньше аргумента.&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p align="left"&gt;&lt;font face="SFRM1200"&gt;Приведите примеры (&amp;gt;1), когда отсутствие инициализатора в объявлении вызовет ошибку компиляции.&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p align="left"&gt;Имеется следующий код:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; char* pString = &amp;quot;C++&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; char val = *(pString + 3);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; char* p = pString + 4;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pString[0] = &amp;#39;D&amp;#39;;&lt;br /&gt;&lt;br /&gt;Определено ли поведение во второй, третьей и четвертой строках листинга. Если да, то каков результат их выполнения, а именно, что будет содержаться в val после выполнения второй строки, в p после&lt;br /&gt;выполнения третьей и в pString[0] после выполнения четвертой строки.&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p align="left"&gt;&lt;font face="SFRM1200"&gt;&lt;em&gt;Здесь требуется некоторый комментарий. В течение семестра мы не рассматривали многомерные массивы и в этом задании студентам предлагается догадаться до того, как это можно сделать в C++ самостоятельно.&lt;br /&gt;&lt;br /&gt;&lt;/em&gt;Для данного типа T тип T* является &amp;quot;указателем на T&amp;quot;. То есть переменная типа T* может хранить адрес объекта типа T. Из этого определения следует, что если в качестве типа T взять T*, то переменная типа T** является указателем на T* и может хранить адрес переменной типа T*.&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;Рассмотрим это на примере:&lt;br /&gt;&amp;nbsp;&amp;nbsp; int main() &lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x = 1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int* pX = &amp;amp;x;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int** ppX = &amp;amp;pX;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;Переменная ppX имеет тип &amp;quot;указатель на указатель на целое&amp;quot; и, следовательно, может хранить адрес объекта, являющегося указателем на целое.&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;Выделение памяти под массив указателей на T (по аналогии) происходит с помощью операции new T*[], тип возвращаемого значения такой операции --- T**.&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&lt;em&gt;Двумерный массив&lt;/em&gt; можно считать одномерным массивом, каждый элемент которого сам является массивом.&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&lt;strong&gt;Задача&lt;/strong&gt;. Используя рассмотренные сведения, написать код выделения памяти под двумерный целочисленный массив из m строк и n столбцов (m и n неизвестны на момент компиляции).&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;Написать код освобождения памяти для полученного массива.&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p align="left"&gt;&lt;font face="SFRM1200"&gt;Дан следующий код:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; #include&amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&amp;nbsp;&amp;nbsp; using namespace std;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&amp;nbsp;&amp;nbsp; enum Number &lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; One = 1,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Two,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Three&lt;br /&gt;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&amp;nbsp;&amp;nbsp; int main() &lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Number a = ...;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; switch(a)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case One:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout&amp;lt;&amp;lt;&amp;quot;One&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case Two:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout&amp;lt;&amp;lt;&amp;quot;Two&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case Three:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout&amp;lt;&amp;lt;&amp;quot;Three&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; default:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout&amp;lt;&amp;lt;&amp;quot;Don&amp;#39;t know&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;Строка Numbers a = ...; - это псевдокод. а инициализируется некоторым значением. Что выведется на экран если a равно One, Two, Three? Переписать приведенный код с использованием инструкции выбора if вместо switch.&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p align="left"&gt;&lt;font face="SFRM1200"&gt;Напишите функции PrefixIncrement и PostfixIncrement которые увеличивают на единицу значение целого числа, переданного в качестве параметра. Обеспечьте, чтобы первая функция имела поведение аналогичное префиксному инкременту, а вторая - постфиксному.&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p align="left"&gt;&lt;font face="SFRM1200"&gt;Почему следующий код вызовет ошибку компиляции:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x = 1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int* p = &amp;amp;x++;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&lt;br /&gt;Скомпилируется ли такой код:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x = 1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int* p = &amp;amp;(++x);&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p align="left"&gt;&lt;font face="SFRM1200"&gt;Почему следующий код вызовет неопределенное поведение:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int* pInt = new int(12);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout&amp;lt;&amp;lt;*pInt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; delete[] pInt;&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p align="left"&gt;&lt;font face="SFRM1200"&gt;Сколько раз выполнится следующий цикл&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 10; i--; i &amp;gt; 10)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Do something&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&lt;br /&gt;Свой ответ объяснить.&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&lt;strong&gt;Подсказка&lt;/strong&gt;. Не торопитесь с ответом.&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p align="left"&gt;&lt;font face="SFRM1200"&gt;Имеется следующий код:&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; class A&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;A(const A&amp;amp; copy)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;//Do something&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; A() {}&lt;br /&gt;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="SFRM1200"&gt;class B&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;A a1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; A a2;&lt;br /&gt;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;Все ли конструкторы, которые при необходимости генерируются компилятором неявно, могут быть им корректно созданы в случае с классом B.&lt;/font&gt;&lt;font face="SFRM1200"&gt;&lt;br /&gt;В частности, будет ли код компилироваться, если к указанному коду добавить main:&lt;/font&gt;&lt;font face="SFRM1200"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; int main() &lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;B b;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;B c = b;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p align="left"&gt;&lt;font face="SFRM1200"&gt;Пусть имеется некоторый пользовательский бинарный оператор, определенный в виде&amp;nbsp; глобальной функции. Как гарантировать, чтобы первый его операнд был модифицируемым(неконстантным) lvalue? (Гарантировать в том смысле, что если это не так, то возникнет ошибка компиляции). Как гарантировать, что его первый операнд&lt;br /&gt;может быть константным объектом? Как это гарантировать, если оператор определен в виде метода класса?&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p align="left"&gt;&lt;font face="SFRM1200"&gt;Имеется следующий код:&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&amp;nbsp;&amp;nbsp; class A{ };&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&amp;nbsp;&amp;nbsp; class B : protected A { };&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&amp;nbsp;&amp;nbsp; class C : public B&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp; public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void SomeMethod()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; A* pA = this;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&amp;nbsp;&amp;nbsp; int main()&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;B b;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;A* pA = &amp;amp;b;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;Какие строки этого кода вызовут ошибку компиляции и почему?&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;Изменилась ли бы ситуация и, если да, то как, если при наследовании B от A использовалось бы закрытое, открытое наследование?&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p align="left"&gt;&lt;font face="SFRM1200"&gt;Имеется следующий код:&lt;/font&gt;&lt;font face="SFRM1200"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; class A&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp; protected:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;int val;&lt;br /&gt;&amp;nbsp;&amp;nbsp; public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;A(int val)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;this-&amp;gt;val = val;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="SFRM1200"&gt;class B : A&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp; public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;B()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;val = 3;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;&lt;br /&gt;Почему код не компилируется при таким образом определенном конструкторе класса B. Измените конструктор B так, чтобы код успешно компилировался.&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="SFRM1200"&gt;Будет ли код компилироваться и почему, если конструктор B определить следующим образом:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; class B : A&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp; public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;B() : val(3) { }&lt;br /&gt;&amp;nbsp;&amp;nbsp; };&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;
&lt;p align="left"&gt;&lt;font face="SFRM1200"&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="left"&gt;&lt;font face="SFRM1200"&gt;&lt;a class="" href="http://itkazan.com/files/folders/alexdemche/entry1975.aspx"&gt;Скачать вопросы в PDF&lt;/a&gt;&lt;/p&gt;&lt;/font&gt;&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1974" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/alexdemche/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://www.itkazan.com/blogs/alexdemche/archive/tags/questions/default.aspx">questions</category><category domain="http://www.itkazan.com/blogs/alexdemche/archive/tags/examine/default.aspx">examine</category></item><item><title>Вакансия в крупном системном интеграторе</title><link>http://www.itkazan.com/blogs/igorsilberg/archive/2008/06/16/CRMVacancy.aspx</link><pubDate>Mon, 16 Jun 2008 09:10:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1805</guid><dc:creator>doctorsolberg</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;Компания ООО «НОРБИТ» (www.norbit.ru)&amp;nbsp; - золотой партнер Microsoft, дочерняя компания «ЛАНИТ» (www.lanit.ru).&lt;br /&gt;В компании 3 специализации (ERP – SAP, Axapta, CRM – MS Dynamics CRM, Департамент собственных решений - госзакупки).&lt;br /&gt;Департамент CRM признан одним из лучших и получил от Microsoft «5 звезд», как лучший по продажам и внедрениям.&lt;br /&gt;В Департамент требуются опытные разработчики.&lt;br /&gt;&lt;br /&gt;Описание вакансии:&lt;/p&gt;&lt;p&gt;Требования:&lt;br /&gt;- ASP.Net;&lt;br /&gt;- JavaScript;&lt;br /&gt;- TSQL;&lt;br /&gt;- HTML/XML/XSLT;&lt;br /&gt;- DOM (для IE от 6.1 и выше);&lt;br /&gt;- Web Services;&lt;br /&gt;- Visual Studio 2003/2005;&lt;br /&gt;- MS SQL Server 2000/2005 Reporting Services.&lt;br /&gt;&lt;br /&gt;Желательно: знание технологии AJAX 1.0, Microsoft SQL Server 2000/2005 Reporting Services&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Обязанности:&lt;br /&gt;- написание Web сайтов;&lt;br /&gt;- написание скриптов;&lt;br /&gt;- написание Web-сервисов;&lt;br /&gt;- настройка системы Microsoft Dynamics CRM 3.0;&lt;br /&gt;- работа с базами данных;&lt;br /&gt;- экспертная помощь младшим разработчикам.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Работа в Москве, но рассматриваются варианты работы над проектами в Казани в местном офисе.&lt;/p&gt;&lt;p&gt;Высылайте резюме на doctorsolberg@gmail.com&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1805" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/igorsilberg/archive/tags/_4004300431043E0442043004_/default.aspx">работа</category></item><item><title>Первая встреча объединенной казанской User Group (Java, .NET, Testing и Agile)</title><link>http://www.itkazan.com/blogs/igorsilberg/archive/2008/05/13/DevMeeting.aspx</link><pubDate>Tue, 13 May 2008 12:45:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1776</guid><dc:creator>doctorsolberg</dc:creator><slash:comments>4</slash:comments><description>&lt;p&gt;14 мая в 19:00 в 413 аудитории Технопарка ИДЕЯ пройдет первая встреча
объединенной казанской User Group (Java, .NET, Testing и Agile).
Содержание:&lt;br /&gt;Александр Шер (Exigen Services, Microsoft MVP) – «Классические» ошибки в ООП&lt;br /&gt;Ляйсан
Лопатченко (Exigen Services, Test Lead) - Качественный успех (В докладе
будут изложены основные концепции создания успешного ПО)&lt;br /&gt;Артем
Воробьев (Exigen Services, Java Developer) - Введение в GWT (Доклад
посвящен применению Google Web Toolkit для эффективной разработки
приложений с использованием технологии AJAX)&lt;/p&gt;&lt;p&gt;Подробности встречи и регистрация здесь: http://kzn.ineta.ru/Events/EventMultiSessionInfo.aspx?Id=694c0229-a48b-47c3-b433-0b42f8b28f2b&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1776" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/igorsilberg/archive/tags/_3204410442044004350447043804_/default.aspx">встречи</category></item><item><title>Лучший в мире броузер. Теперь и под Windows</title><link>http://www.itkazan.com/blogs/raimon/archive/2008/03/24/windows_2D00_safari_2D00_release.aspx</link><pubDate>Mon, 24 Mar 2008 18:18:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1759</guid><dc:creator>Raimon</dc:creator><slash:comments>6</slash:comments><description>Выпущен первый релизный Safari под Windows! По заявлениям Apple, Safari самый быстрый!...(&lt;a href="http://www.itkazan.com/blogs/raimon/archive/2008/03/24/windows_2D00_safari_2D00_release.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1759" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/raimon/archive/tags/Safari/default.aspx">Safari</category><category domain="http://www.itkazan.com/blogs/raimon/archive/tags/Perfomance/default.aspx">Perfomance</category><category domain="http://www.itkazan.com/blogs/raimon/archive/tags/Browser/default.aspx">Browser</category></item><item><title>Служители дьявола или новая востребованная специализация</title><link>http://www.itkazan.com/blogs/rinat_sadykov/archive/2008/01/21/1714.aspx</link><pubDate>Mon, 21 Jan 2008 06:13:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1714</guid><dc:creator>Rinat_Sadykov</dc:creator><slash:comments>8</slash:comments><description>&lt;p&gt;Все&amp;nbsp;прекрасно знают, что в Казани не хватает опытных программистов. А вот&amp;nbsp;имеются еще такие специалисты, про которых можно сказать, что в нашем любимом городе их просто нет или непростительно мало. Есть несколько ВУЗов,&amp;nbsp;множество предприятий - разработчиков программного обеспечения, но их можно&amp;nbsp;на пальцах&amp;nbsp;сосчитать. Кто же они? Да, это специалисты по тестированию программного обеспечения. Именно специалисты, а не те, кто может потыхать по кнопкам и иногда находить ошибки. &lt;/p&gt;
&lt;p&gt;Почему их я по дружески назвал служителями дьявола? Те, кто знает основы тестирования, понимают, о чем я. А те кто не знает, и хочет участвовать в разработке&amp;nbsp; КАЧЕСТВЕННОГО, НАДЕЖНОГО ПО, то в путь! Благо, информации и литературы про тестирование в просторах интернета много. Если что, пишите мне, с радостью постараюсь помочь, правда, все по английски. И, привет дьяволу! &lt;img src="http://www.itkazan.com/emoticons/emotion-11.gif" alt="Cool" /&gt;&lt;/p&gt;&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1714" width="1" height="1"&gt;</description></item><item><title>полезная книжка по информатике для начинающих</title><link>http://www.itkazan.com/blogs/dmitryshm/archive/2007/12/28/1681.aspx</link><pubDate>Fri, 28 Dec 2007 11:28:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1681</guid><dc:creator>dmitryshm</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Известная книжка Окулова по информатике прекрасно подойдет тем, кто начинает изучать программирование.&lt;a href="http://itkazan.com/blogs/dmitryshm/okulov.zip"&gt;okulov.zip&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1681" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/dmitryshm/archive/tags/_3F0440043E043304400430043C043C04380440043E04320430043D0438043504_/default.aspx">программирование</category></item><item><title>Приглашаем на первую в новом году встречу .NET разработчиков, целиком посвященную LINQ</title><link>http://www.itkazan.com/blogs/igorsilberg/archive/2007/12/17/JanuaryLINQMeeting.aspx</link><pubDate>Mon, 17 Dec 2007 09:50:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1669</guid><dc:creator>doctorsolberg</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;Подробности встречи и регистрация &lt;a class="" href="http://kzn.ineta.ru/Events/EventInfo.aspx?Id=749f45bf-86b9-49aa-9153-20b52d3b6d93" target="_blank"&gt;здесь&lt;/a&gt;!&lt;/p&gt;&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1669" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/igorsilberg/archive/tags/_3204410442044004350447043804_/default.aspx">встречи</category><category domain="http://www.itkazan.com/blogs/igorsilberg/archive/tags/.net/default.aspx">.net</category><category domain="http://www.itkazan.com/blogs/igorsilberg/archive/tags/LINQ/default.aspx">LINQ</category></item><item><title>Бесплатные семинары от SoftLine</title><link>http://www.itkazan.com/blogs/dmitryshm/archive/2007/12/14/softline.aspx</link><pubDate>Thu, 13 Dec 2007 22:13:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1667</guid><dc:creator>dmitryshm</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Уважаемые господа!&lt;/p&gt;
&lt;p&gt;Компания Softline и корпорация Microsoft приглашают Вас 25 декабря 2007 г., принять участие в БЕСПЛАТНОМ семинаре на тему : &lt;b&gt;&amp;quot;&lt;/b&gt;&lt;b&gt;Защищенная ИТ-инфраструктура - фундамент успешного бизнеса&lt;/b&gt;&lt;b&gt;!&amp;quot;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Мероприятие будет проходить по адресу: г. Казань, ул. Достоевского, &amp;nbsp;д. 18/75, офисный центр «Сувар-Казань», конференц-зал&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Под эффективно работающей ИТ - инфраструктурой мы понимаем систему, которая помогает усовершенствовать текущие бизнес-процессы, повысить общекорпоративную отдачу и уменьшить сроки выполнения работ. Для того, чтобы достичь поставленной цели, ИТ - инфраструктура должна быть динамичной, эффективной, надежной и безопасной, она должна быть защищена от внешних воздействий и при этом без промедлений и простоев обслуживать любые хозяйственные операции.&lt;/p&gt;
&lt;p&gt;На семинаре участники будут ознакомлены с продуктовыми линейками Microsoft по защите информационных систем, такими как ISA Server 2006, ForeFront, особое внимание будет уделено новому продукту - Forefront Client Security. Вы сможете увидеть демонстрацию этого продукта, узнать о новых возможностях и задать интересующие вопросы представителям компаний Softline и Microsoft.&lt;/p&gt;
&lt;p&gt;На семинар приглашаются технические директора и руководители IT-департаментов, инженеры, заинтересованные в стабильности работы IT-инфраструктуры компании.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;ПРОГРАММА СЕМИНАРА:&lt;/p&gt;
&lt;table class="" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;09.30 - 10.00&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;Регистрация участников, кофе&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;10.00 - 10.15&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;Вступительное слово&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;10.15 - 10.30&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;Стратегия Microsoft в области информационной безопасности. Обзор семейства продуктов Forefront&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;10.30 - 11.30&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;Защита периметра сети с помощью ISA Server 2006&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;11.30 - 11.50&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;Перерыв, кофе&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;11.50 - 12.30&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;Защита рабочих станций и файловых серверов посредством Forefront Client Security&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;12.30 - 13.20&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;Решение Forefront Server Security для защиты электронной почты и серверов совместной работы&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;13.20 - 14.00&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p&gt;Сессия вопросов и ответов.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;С докладами выступят Алексей Галков, компания Microsoft и Максим Косинов, специалист компании Softline&lt;/p&gt;
&lt;p&gt;Зарегистрироваться можно:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://softline/"&gt;http://softline/&lt;/a&gt;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;e-mail: &lt;a href="mailto:info.kzn@softline.ru"&gt;mailto:info.kzn@softline.ru&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;tel.: +7 (843) 527-98-50&lt;/p&gt;
&lt;p&gt;ПРЕДВАРИТЕЛЬНАЯ РЕГИСТРАЦИЯ&amp;nbsp; ЯВЛЯЕТСЯ ОБЯЗАТЕЛЬНОЙ!&lt;/p&gt;
&lt;p&gt;======================================================&lt;/p&gt;
&lt;p&gt;Контактное лицо: Ольга Миняйло, менеджер по маркетингу &lt;/p&gt;
&lt;p&gt;tel.: +7 (843) 527-98-50&lt;/p&gt;
&lt;p&gt;А вот еще одно приглашение...&lt;/p&gt;
&lt;p&gt;Приглашаем Вас &lt;b&gt;21.12.2007&lt;/b&gt; принять участие в&lt;b&gt; БЕСПЛАТНОМ «Тест-драйве &lt;/b&gt;&lt;b&gt;Windows server&lt;/b&gt;&lt;b&gt; 2008».&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Тест-драйв представляет собой мастер-класс, где каждый посетитель будет обеспечен отдельным рабочим местом и материалами, необходимыми для эффективного изучения. &lt;/p&gt;
&lt;p&gt;Тест-драйв это отличный шанс, за короткое время, освоить навыки работы с новым продуктом. Тест-драйв будет проходить в Технопарке «Идея», ул. Петербургская, д.50 с 9.30 до-12.30 и с 13.30-16.30&lt;/p&gt;
&lt;p&gt;Предварительная регистрация на мероприятие является обязательной. Дополнительные вопросы и регистрация у менеджера по маркетингу Softline в Казани Ольги Миняйло &lt;b&gt;&lt;a title="mailto:olgami@softline.ru" href="mailto:olgami@softline.ru"&gt;olgami@softline.ru&lt;/a&gt; &lt;/b&gt;, &lt;b&gt;тел.: (843) 527-98-50&lt;/b&gt;&lt;/p&gt;&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1667" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/dmitryshm/archive/tags/_410435043C0438043D0430044004_/default.aspx">семинар</category></item><item><title>Синтаксис Семантического веба</title><link>http://www.itkazan.com/blogs/kdenisov/archive/2007/12/10/1666.aspx</link><pubDate>Mon, 10 Dec 2007 08:00:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1666</guid><dc:creator>kdenisov</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Технологии Веб нового поколения должны обеспечивать возможности автоматизированной интерпретации и обработки информации, семантической интероперабельности информационных ресурсов. В этих условиях уже недостаточно располагать синтаксическим описанием XML-документов с помощью DTD или XML Schema. Например, при обмене документами, описанными средствами этих языков, обе обменивающиеся стороны должны одинаковым образом понимать смысл используемых в документах типов элементов и атрибутов элементов, а также содержащихся в них гиперссылок, о чем заранее должны быть приняты соответствующие договоренности, описанные вербальным или иным образом.&lt;/p&gt;
&lt;p&gt;Необходимость решения указанных задач вызвала потребность в таких средствах формального описания семантики XML-данных, которые бы позволяли анализировать и обрабатывать их с помощью программного обеспечения.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Первым шагом консорциума W3C в рассматриваемом направлении было создание стандартов RDF (Resource Definition Framework) и RDFS (RDF Schema).&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;В RDF-спецификации объявляется некоторое множество ресурсов, для каждого из которых определяются пары &amp;quot;&lt;em&gt;свойство-значение&lt;/em&gt;&amp;quot;. Информационные ресурсы в RDF - это ресурсы Веб, идентифицируемые уникальным образом с помощью их URI. Они могут также представлять собой коллекции других информационных ресурсов или литералов, называемые контейнерами. Допускаются контейнеры типа мультимножества, последовательности и альтернативы. Значения свойств задаются литерально либо могут быть другими ресурсами, которые представляются, в свою очередь, их свойствами. &lt;u&gt;Таким образом, свойства могут определять и связи между ресурсами.&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;Смысл выражается посредством языка RDF, который кодирует его с помощью множества &lt;strong&gt;&lt;em&gt;триплетов&lt;/em&gt;&lt;/strong&gt; [triple], где каждый триплет состоит из субъекта, глагола и объекта элемен&amp;shy;тар&amp;shy;но&amp;shy;го пред&amp;shy;ло&amp;shy;жения. Такие триплеты можно записать с по&amp;shy;мощью тэгов языка XML. В языке RDF документ состоит из утверждений о том, что нечто (человек, веб-страница или что-либо ещё) имеет определённое отношение (как то «быть сестрой», «быть автором») с некоторым определённым значением (другой человек, другая веб-страница). Подобная структура оказывается весьма естественной для описания подавляющего большинства машинно-обрабатываемых данных. Субъект и объект задаются с помощью Единообразного Идентификатора Ресурса (Uniform Resource Identifier, URI), подобно ссылкам на веб-страницах. (URL — Универсальный Локатор Ресурса (Universal Resource Locator) — представляет собой наиболее распространённый тип URI). Глаголы тоже задаются посредством URI, что позволяет определять новое понятие или новый глагол, просто указав его URI-адрес в Сети. &lt;/p&gt;
&lt;p&gt;&lt;em&gt;Человеческий язык процветает благодаря тому, что одно и тоже слово может иметь несколько значений; но это совсем не так для языка машинного. Представьте себе, например, что я нанимаю клоунов-курьеров для доставки воздушных шариков моим клиентам на их дни рождения. Совершенно не кстати, эта развлекательная служба перекачает мою базу данных с адресами клиентов себе, не зная, что «адрес» в моей базе данных — это то место, куда доставляются счета, и что большинство из них — абонентские ящики в почтовых отделениях. В итоге мои клоуны повеселят почтовых работников — что само по себе, возможно, не так уж и плохо, но, очевидно, это не то, чего хотелось изначально. Подобная проблема решается использованием различных URI для каждого конкретного понятия. Почтовый адрес тогда можно будет отличить от адреса проживания, и оба эти понятия, в свою очередь, можно будет отличить от понятия «адресовать речь кому-либо» [an address that is a speech].&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Из триплетов языка RDF формируются сети информации о взаимосвязанных вещах. Поскольку RDF использует URI-идентификаторы для кодирования данной информации в документе, эти самые URI-идентификаторы гарантируют то, что каждое понятие, используемое в документе — это не просто слово, а нечто, привязанное к единому определению, которое каждый желающий может найти в Сети. Например, представим себе, что у нас есть доступ к нескольким базам данных о людях, содержащим их адреса. Если теперь мы хотим найти тех людей, которые живут в районе с неким заданным почтовым индексом, то нам нужно будет знать, какое именно поле в каждой из баз данных представляет собой имя, а какой — почтовый индекс. &lt;em&gt;Это можно выразить на языке RDF в виде: «(поле 5 в базе данных A)(является полем типа)(почтовый индекс)», используя URI-идентификаторы вместо слов для каждого термина&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Здесь я описал как-бы синтаксис без синтаксиса ) все на основе знаменитой статьи Tim Bernes-Lee&lt;/p&gt;
&lt;p&gt;Далее, я напишу, что, на самом деле,&amp;nbsp;не так все и радужно в мире семантики :) есть критика и, кстати говоря,&amp;nbsp;много критики.. Постараюсь осветить все альтернативные взгляды на семантический веб.&lt;/p&gt;
&lt;p&gt;И еще несколько ссылок на &lt;u&gt;русскоязычные &lt;/u&gt;ресурсы:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.semantictools.ru/"&gt;http://www.semantictools.ru/&lt;/a&gt;&amp;nbsp;- сайт посвященный полностью семантическому вебу и онтологиям&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.semanticweb.narod.ru/"&gt;http://www.semanticweb.narod.ru/&lt;/a&gt;&amp;nbsp;- тоже отличный сайт о SW&lt;/p&gt;&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1666" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/kdenisov/archive/tags/Semantic+Web/default.aspx">Semantic Web</category><category domain="http://www.itkazan.com/blogs/kdenisov/archive/tags/RDF/default.aspx">RDF</category></item><item><title>Для затравки.</title><link>http://www.itkazan.com/blogs/kdenisov/archive/2007/11/29/1657.aspx</link><pubDate>Thu, 29 Nov 2007 09:07:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1657</guid><dc:creator>kdenisov</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Проекты семантического веба. Спасибо Юрию Лифшицу за ссылки :)&lt;/p&gt;&lt;font face="CMSY10" size="2"&gt;
&lt;p align="left"&gt;• &lt;/font&gt;&lt;font face="SFRM1000" size="2"&gt;Поисковая система SHOE (http://www.cs.umd.edu/projects/plus/SHOE/search/): поиск в Семантическом Вебе.&lt;/p&gt;&lt;/font&gt;&lt;font face="CMSY10" size="2"&gt;
&lt;p align="left"&gt;• &lt;/font&gt;&lt;font face="SFRM1000" size="2"&gt;Jena (http://jena.sourceforge.net): среда разработки приложений для семантического веба, включает исполнитель запросов.&lt;/p&gt;&lt;/font&gt;&lt;font face="CMSY10" size="2"&gt;
&lt;p align="left"&gt;• &lt;/font&gt;&lt;font face="SFRM1000" size="2"&gt;Simile (http://simile.mit.edu): Семантический веб для электронных библиотек.&lt;/p&gt;&lt;/font&gt;&lt;font face="CMSY10" size="2"&gt;
&lt;p align="left"&gt;• &lt;/font&gt;&lt;font face="SFRM1000" size="2"&gt;Protege (http://protege.stanford.edu): редактор онтологий из Стенфорда&lt;/p&gt;&lt;/font&gt;&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1657" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/kdenisov/archive/tags/Stanford/default.aspx">Stanford</category><category domain="http://www.itkazan.com/blogs/kdenisov/archive/tags/Semantic+Web/default.aspx">Semantic Web</category></item><item><title>Семантический Веб</title><link>http://www.itkazan.com/blogs/kdenisov/archive/2007/11/29/1656.aspx</link><pubDate>Thu, 29 Nov 2007 08:56:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1656</guid><dc:creator>kdenisov</dc:creator><slash:comments>5</slash:comments><description>&lt;p&gt;&lt;strong&gt;Новая форма представления содержимого WWW значимадля компьютеров и приведет к революционным изменениям в возможностях сети.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Сегодня я решил представить вам избранное из статьи основателя и действующего директора W3C Tim Berners-Lee, напечатанной в 2001 году в журнале Scientific American.&amp;nbsp; Статья это являлась некоторым итогом работы самого &lt;strong&gt;Tim Berners-Lee&lt;/strong&gt; и стартом исследований для ведущих умов Computer Science. Называется она очень просто и лаконично &amp;quot;The Semantic Web&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;Итак прелюдия - недалекое будущее.&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Домашний центр развлечений убавил громко играющую классику Битлз &amp;quot;We Can Work It Out&amp;quot;, когда зазвонил телефон. Пока Пит поднимал трубку, телефон отправил сообщения всем домашним устройствам, которые имеют регулятор грмкости. Его сестра Люси звонила от доктора: &amp;quot;Маме необходимо найти специалиста и пройти двухненедельный курс физтерапии. Я отправлю запрос моему агенту.&amp;quot; Пит предложил ей отвезти их.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;У доктора Люси запустила Semantic Web agent в браузере ее КПК. Агент сразу же запросил&amp;nbsp; информацию о &lt;em&gt;назначенном лечении&lt;/em&gt; у агента Доктора, заглянул в списки провайдеров, и выбрал тех, чьи &lt;em&gt;словия&lt;/em&gt; подоходят под страховку, кто находится в &lt;em&gt;радиусе 20 миль&lt;/em&gt; от ее дома и имеют &lt;em&gt;высшие рейтинги&lt;/em&gt;, от влиятельных и уважаемых экспертов. И затем, он провел поиск по совпадениям во времени назначении (каждая клиника публикует расписания приемов на своих сайтах). В результате Питу и Люси был представлен список возможных расписаний приемов врачей удовлетворяющих всем заданным условиям. (выделенные ключевые слова обозначают термы в семантическом смысле, которые заданы агентами Семантического Веба)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Expressing Meaning&lt;br /&gt;&lt;/strong&gt;Пит и Люси не смогут использовать своих агентов для подобных задач, с сегодняшним состоянием WWW, однако это станет возможным когда WWW разовьется в семантический веб в ближайшем будущем.&lt;br /&gt;Большая часть нынешнего веб контента представлена в форме которая удобна и понятна человеку, но не компьютеру! Для компьютера сейчас безразлично какую информацию он забирает ежедневно сотнями мегабайт, однако было бы неплохо, если бы он мог бы использовать все свои тысячи мегагерц более рационально и извлекать знания из полученного набора символов и слов. Сейчас Компьютеры в принципе могут сознательно парсить страницы по некторому шаблону и извлекать семантику: это домашняя страница Клиники Хартмана, этот линк ведет к CV доктора Хартмана и т.д..&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;Семантический веб предлагает структуру значимого &lt;em&gt;(в смысле осознанного)&lt;/em&gt; контента веб страниц, предоставляет среду, где программные агенты гуляя от страницы к странице, легко выполняют осмысленные запросы от пользователей. Например, наш агент из примера, зайдя на страницу клиники, нашел там ключевые слова &amp;quot;treatment, medicine, physical, therapy&amp;quot;, и помимо этого нашел что доктор Хартман находится в клинике по понедельникам, средам и пятницам. И все эти факты известны без использования каких либо техник искуственного интеллекта. Вся эта семантика закодирована внутри страницы обычным офис-менеджером (который не имеет степени по Comp.Sci.) с помощью специального программного обеспечения, для создания семантических страниц.&lt;/p&gt;
&lt;p&gt;Семантический Веб это не какой-то отдельный Веб, - это расширение над нынешним, где информация введена специальным образом, облегчающее взаимодействие людей и компьютеров. Первые пробные шаги по узкой тропе интеграции семантического веба в нынешний уже делаются. И в ближайшем будущем эти разработки помогут сделать значительный рывок вперед в задачах обучения машин &amp;quot;понимать&amp;quot; данные которые они находят и показывают.&lt;/p&gt;
&lt;p&gt;Особое свойство современного WWW - это его универсальность. Мошь гипертекста в том что он может связать все со всем. Веб технологии, следовательно не делают различий между коммерческой и учебной информацией, между культурами, языками пр. Поиск по ключевым словам выдают бесчисленные множества страниц, мало имеющих отношение к сделанному запросу. И тут все должно изменится и приходом и активизацией парадигмы семантического веба.&lt;br /&gt;Поисковая система сможет выдавать только те сайты, где упоминалось в точности искомое понятие, а не произвольные страницы. Проблема только в том что компьютер не имеет &lt;em&gt;знаний&lt;/em&gt; о словах запроса и запросе в целом. Поэтому необходима предварительная процедура Объединения знаний.&lt;br /&gt;Семантический веб, именуя всякое с помощью URI идентификатора, даст возможность каждому выражать новые понятия, которые он изобретает, с минимальными усилиями. Его универсальный логический язык позволит постепенно связать все эти понятия в универсальную Сеть. Эта структура сделает знания и достижения человечества доступными для анализа программными агентами и предложит новый класс средств, с помощью которых мы сможем вместе жить, работать и учиться.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;В следующих выпусках я расскажу об архитектуре, и синтаксисе семантического веба. &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Кроме того среди ближайших поднимаемых вопросов будут: &lt;em&gt;квантовые компьютеры&lt;/em&gt; (поскольку в ближайшее время Гугл представит всем прототип промышленного квантового компьютера), &lt;em&gt;техники реализации полнотекстовых поисковых движков на своих сайтах и прочее из мира Интернет&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt;Если кого что интересует еще пишите в комментах - эти темы постараюсь освещать раньше.&lt;/p&gt;
&lt;p&gt;Спасибо и Удачи :)&lt;/p&gt;&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1656" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/kdenisov/archive/tags/Computer+Science/default.aspx">Computer Science</category><category domain="http://www.itkazan.com/blogs/kdenisov/archive/tags/Semantic/default.aspx">Semantic</category><category domain="http://www.itkazan.com/blogs/kdenisov/archive/tags/WWW/default.aspx">WWW</category><category domain="http://www.itkazan.com/blogs/kdenisov/archive/tags/W3C/default.aspx">W3C</category></item><item><title>Всем привет!</title><link>http://www.itkazan.com/blogs/kdenisov/archive/2007/11/27/1652.aspx</link><pubDate>Tue, 27 Nov 2007 10:30:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1652</guid><dc:creator>kdenisov</dc:creator><slash:comments>5</slash:comments><description>&lt;p&gt;Всем привет!&lt;/p&gt;
&lt;p&gt;Показалось мне, что на itkazan.ru как-то мало внимания уделяется основе основ программирования и разработки, а именно Computer Science (Теоретическая информатика), поэтому, с Вашего позволения, я постараюсь немного разбавить разговоры о технологиях и средствах разработки, моими мыслями об основах и последних (современных) разработках в области теоретической базы программерской кухни.&lt;/p&gt;
&lt;p&gt;Писать я буду о темах интересующих меня в последнее время а именно о интересных новинках за неделю с различных Computer Science ресурсов, а в большинстве своем arxiv.org. &lt;/p&gt;
&lt;p&gt;Темы интересующие меня там: Statistic ( &lt;a href="http://arxiv.org/archive/stat"&gt;&lt;font color="#0a4b72"&gt;http://arxiv.org/archive/stat&lt;/font&gt;&lt;/a&gt;&amp;nbsp;), большая часть разделов Computer Science( &lt;a href="http://arxiv.org/list/cs/new%22%3EComputer"&gt;&lt;font color="#0a4b72"&gt;http://arxiv.org/list/cs/new&lt;/font&gt;&lt;/a&gt;&amp;nbsp;), Quantum Algebra&amp;nbsp; ( &lt;a href="http://arxiv.org/list/math.QA/recent%22%3EQuantum"&gt;&lt;font color="#0a4b72"&gt;http://arxiv.org/list/math.QA/recent&lt;/font&gt;&lt;/a&gt;&amp;nbsp;) и&amp;nbsp;Dynamical Systems ( &lt;a href="http://arxiv.org/list/math.DS/recent"&gt;&lt;font color="#0a4b72"&gt;http://arxiv.org/list/math.DS/recent&lt;/font&gt;&lt;/a&gt;&amp;nbsp;). &lt;/p&gt;
&lt;p&gt;Кроме этого буду выкладывать мое мнение о последних купленных и прочитанных книгах.&lt;/p&gt;
&lt;p&gt;А также помимо всего прочего, постараюсь давать некоторые обзорные материалы по авангарду Computer Science и WWW - Семантическому вебу, Квантовым компьютерам, поисковым технологиям и различные подобласти Information Retrievial и Data Mining.&lt;/p&gt;
&lt;p&gt;Комментарии и пожелания приветствуются!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1652" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/kdenisov/archive/tags/Computer+Science/default.aspx">Computer Science</category><category domain="http://www.itkazan.com/blogs/kdenisov/archive/tags/Data+Mining/default.aspx">Data Mining</category><category domain="http://www.itkazan.com/blogs/kdenisov/archive/tags/Arxiv.Org/default.aspx">Arxiv.Org</category></item><item><title>Отчет по прошедшей встрече (09.11.2007) и конкурс .net юзер-групп</title><link>http://www.itkazan.com/blogs/igorsilberg/archive/2007/11/20/NovemberNetUGReport.aspx</link><pubDate>Tue, 20 Nov 2007 12:26:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1620</guid><dc:creator>doctorsolberg</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Итак! Наконец-то нас собралось столько, что&amp;nbsp;с трудом хватило стульев&amp;nbsp;:) Буду краток, по моему встреча получилась отличная! Спасибо большое докладчикам: Александру Шеру за его глубокие технические доклады по ASP.NET AJAX (знаю, знаю, не все переварили, мслевел 400 как минимум:)), Даниле Корневу за веселый и познавательный доклад о MS SQL FileStream. Небольшой &lt;a class="" href="http://itkazan.com/photos/meeting_photo/category1461.aspx" target="_blank"&gt;фотоотчет здесь&lt;/a&gt; (&lt;a class="" href="http://itkazan.com/photos/meeting_photo/1461/slideshowpro.aspx" target="_blank"&gt;слайдшоу&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;И еще новость! Наше .NET сообщество участвует во всероссийском &lt;a class="" href="http://www.gotdotnet.ru/News/Events/507297.aspx" target="_blank"&gt;конкурсе юзергрупп&lt;/a&gt;! Так что пожалуйста,&amp;nbsp;активно&amp;nbsp;голосуйте за понравившиеся доклады на &lt;a href="http://kzn.ineta.ru/"&gt;http://kzn.ineta.ru&lt;/a&gt;, оставляйте отзывы, участвуйте во встречах, читайте доклады и получайте призы:)&lt;/p&gt;
&lt;p&gt;P.S. Не забудьте про &lt;a class="" href="http://kzn.ineta.ru/Events/EventInfo.aspx?ID=7c116c85-6a45-4f1d-ae4d-51e71ed8d962" target="_blank"&gt;студенческую встречу 23-го ноября&lt;/a&gt;!&lt;br /&gt;P.P.S. Если кто еще не в курсе, вышла Visual Studio 2008!&lt;/p&gt;&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1620" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/igorsilberg/archive/tags/_3A043E043D043A04430440044104_/default.aspx">конкурс</category><category domain="http://www.itkazan.com/blogs/igorsilberg/archive/tags/_3204410442044004350447043804_/default.aspx">встречи</category><category domain="http://www.itkazan.com/blogs/igorsilberg/archive/tags/.net/default.aspx">.net</category><category domain="http://www.itkazan.com/blogs/igorsilberg/archive/tags/_3E044204470435044204_/default.aspx">отчет</category></item><item><title>Правила работы над проектами Visual C++</title><link>http://www.itkazan.com/blogs/dmitryshm/archive/2007/11/17/visual-c.aspx</link><pubDate>Sat, 17 Nov 2007 16:45:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1609</guid><dc:creator>dmitryshm</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;&lt;em&gt;&lt;a href="http://itkazan.com/blogs/dmitryshm/работа%20над%20проектами%20в%20FunZai.pdf"&gt;работа над проектами в FunZai.pdf&lt;/a&gt;&lt;/em&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;Захотел опубликовать некое подобие стандарта для работы отдела, практикующего написание кода и ведение проектов Visual C++. Эта статья основана на замечательной книге &amp;quot;С++ Coding Standards: 101 Rules, Guidelines and Best Practices&amp;quot; by Herb Sutter, Andrei Alecsandrescu. Кое что добавил я &amp;quot;от себя&amp;quot;. В кавычках, т.к. эти мысли все равно не могу себе присвоить. Где-то я все-таки это вычитал, как и многие из нас,&amp;nbsp;публикуя что-то более-менее стоящее.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Приследую две цели. Самое главное --- замечания и предложения, ведь редко кто публикует нечто подобное. Следующая цель --- помочь программистам в их деле, особенно ведущим программистам и менеждерам проектов в тяжком труде. Эта дока поможет создать в команде рабочую обстановку и может избавить от детских вопросов и ошибок.&lt;/div&gt;&lt;img src="http://www.itkazan.com/aggbug.aspx?PostID=1609" width="1" height="1"&gt;</description><category domain="http://www.itkazan.com/blogs/dmitryshm/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://www.itkazan.com/blogs/dmitryshm/archive/tags/_4104420430043D043404300440044204_/default.aspx">стандарт</category><category domain="http://www.itkazan.com/blogs/dmitryshm/archive/tags/_3F0440043004320438043B043004_/default.aspx">правила</category></item><item><title>Библиотека Diluculum для работы со скриптовым языком Lua из С++</title><link>http://www.itkazan.com/blogs/dmitryshm/archive/2007/11/16/diluculum-lua.aspx</link><pubDate>Fri, 16 Nov 2007 21:06:00 GMT</pubDate><guid isPermaLink="false">a0bcd6ff-3bec-41dc-9fcd-885f6beec21b:1603</guid><dc:creator>dmitryshm</dc:creator><slash:comments>5</slash:comments><description>&lt;p&gt;&lt;strong&gt;Коротко о Lua&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Lua&amp;nbsp;— это скриптовый язык. Он используется, в основном, в игровой индустрии. Это связано с тем, что большинство игр написано на С++, а Lua часто используется вместе с С++. Для получения информации по Lua достаточно в Вашей любимой поисковой системе набрать &amp;quot;скриптовый язык Lua&amp;quot;. Скорее всего будет найдена &lt;a href="http://ru.wikipedia.org/wiki/Lua" target="_blank"&gt;&lt;font color="#000080"&gt;статья в википедии&lt;/font&gt;&lt;/a&gt;. Полезная статья. С нее Вы сможете зайти на несколько полезных сайтов, посвященных Lua и всевозможным утилитам и библиотекам, прочему Lua-инструментарию. Русский перевод официальной доки можно найти &lt;a href="http://www.botik.ru/~rldp/mysql/mysqldev/glava04.htm" target="_blank"&gt;&lt;font color="#000080"&gt;здесь&lt;/font&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Коротко о Diluculum&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Несмотря на то, что сам по себе Lua хорош, его надо уметь использовать из С++. Чтобы это можно было делать, в Lua были встроены механизмы, основанные на работе со стеком и прочими вещами, которые, вообще говоря, неудобны в использовании. Написано несколько библиотек для удобной работы с Lua. Здесь речь будет идти о библиотеке Diluculum. Мне она понравилась больше всех остальных. На данный момент она используется весьма редко, т.к. работает с Lua 5.1, что интерфейсно не совместимо с Lua 5.0 (там были переделаны некоторые заголовочные файлы). Для достижения совместимости с Lua 5.0 можно воспользоваться советами пользователей Lua из многочисленных форумов. В любом случае, если Вы пишете новую программу, Lua версий ниже 5.1 для Вас уже не существует. Из-за того, что Diluculum является сравнительно новой библиотекой, она оказалась весьма продуманной с точки зрения удобств использования.&lt;/p&gt;
&lt;p&gt;Приведу перевод &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/pag-UsersGuide.html" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum Quick User&amp;#39;s Guide&lt;/font&gt;&lt;/a&gt; на русский язык. Постараюсь лично от себя ничего не добавлять, т.к. автор и так хорошо изложил идеи. Надеюсь, что благодаря этой статье богатство Lua станет доступно более широкому кругу пользователей C++. Стоит добавить, что подобные библиотеки для работы с Lua есть и для C#, и для Java.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Diluculum Quick User&amp;#39;s Guide&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Введение&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Diluculum — это библиотека, предназначенная для гармоничного сосуществования кода на С++ и кода на Lua. В этом смысле библиотека может предложить следующее:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p style="MARGIN-BOTTOM:0cm;"&gt;Удобный доступ к Lua-данным. Это достигается через использование объектов класса &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/classDiluculum_1_1LuaState" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum::LuaState&lt;/font&gt;&lt;/a&gt;, который инкапсулирует lua_State* (информация по lua_State находится в документации по Lua).&lt;/p&gt;
&lt;li&gt;
&lt;p style="MARGIN-BOTTOM:0cm;"&gt;Неплохой способ делать доступными функции С++ из Lua через использование макроса &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/LuaWrappers_8hpp.html#3daed6c71e578b4624baffe58e0eb125" target="_blank"&gt;&lt;font color="#000080"&gt;DILUCULUM_WRAP_FUNCTION()&lt;/font&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;li&gt;
&lt;p&gt;Ограниченный, однако весьма удобный, способ регистрировать классы на С++ в Lua (чтобы можно было создавать объекты этих классов из Lua [так называемые Lua-managed объекты]). Это можно сделать&amp;nbsp;посредством использования макросов &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/LuaWrappers_8hpp.html#abc543a317b1623f2079f75155eb3a21" target="_blank"&gt;&lt;font color="#000080"&gt;DILUCULUM_BEGIN_CLASS()&lt;/font&gt;&lt;/a&gt;, DILUCULUM_END_CLASS() и &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/LuaWrappers_8hpp.html#917538e1624f2dd2fa8c3d9a8e1a2fc8" target="_blank"&gt;&lt;font color="#000080"&gt;DILUCULUM_REGISTER_OBJECT()&lt;/font&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p style="MARGIN-BOTTOM:0cm;"&gt;В следующих параграфах описывается каждый из этих трех пунктов более детально. Замечание: Diluculum включает юнит-тесты для каждой его особенности в папке Tests дистрибутива с исходниками. Они могут использоваться как хорошие примеры использования библиотеки.&lt;/p&gt;
&lt;p style="MARGIN-BOTTOM:0cm;"&gt;&lt;strong&gt;&lt;i&gt;Получение доступа к данным Lua State из C++&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Класс &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/classDiluculum_1_1LuaState.html" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum::LuaState&lt;/font&gt;&lt;/a&gt; инкапсулирует lua_State*, хендл, через который идет работа с Lua-интерпретатором. Lua часто используется, как конфигурационный язык. Для этой цели очень хорошо использовать объекты класса &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/classDiluculum_1_1LuaState.html" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum::LuaState&lt;/font&gt;&lt;/a&gt;. Пусть у нас имеется конфигурационный файл config.lua какого-нибудь приложения.&lt;/p&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;-- A configuration file&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;FavoriveColor = &amp;quot;blue&amp;quot;&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;FavoritePiApproximation = 22 / 7&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;UserInfo = {&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Name = &amp;quot;Fulano de Tal&amp;quot;,&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Age = 33,&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LikeLargeIcons = true&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;}&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;WindowSize = { 456, 234 };&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;function EmphasizeFunc(s)&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &amp;quot;&amp;lt;EMPH&amp;gt;&amp;quot;..s..&amp;quot;&amp;lt;/EMPH&amp;gt;&amp;quot;&amp;nbsp;&lt;/blockquote&gt;
&lt;blockquote&gt;end&lt;/blockquote&gt;
&lt;p&gt;Для того, чтобы получить информацию из этого файла и использовать ее из С++, первым делом создадим объект класса Diluculum::LuaState, как показано в следующем листинге.&lt;/p&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;#include &amp;lt;&lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/LuaState_8hpp.html" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum/LuaState.hpp&lt;/font&gt;&lt;/a&gt;&amp;gt;&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;//..&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;Diluculum::LuaState ls;&lt;/blockquote&gt;
&lt;blockquote&gt;ls.&lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/classDiluculum_1_1LuaState.html#698225e4ad32ebe8724026961b7654e1" target="_blank"&gt;&lt;font color="#000080"&gt;doFile&lt;/font&gt;&lt;/a&gt;(&amp;quot;config.lua&amp;quot;);&lt;/blockquote&gt;
&lt;p&gt;Теперь мы можем использовать operator[] для получения переменных, а затем и их значений.&lt;/p&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;const std::string favColor = ls[&amp;quot;FavoriteColor&amp;quot;].value().asString();&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;const double favApprox = ls[&amp;quot;FavoritePiApproximation&amp;quot;].value().asNumber();&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;const std::string userName = ls[&amp;quot;UserInfo&amp;quot;][&amp;quot;Name&amp;quot;].value().asString();&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;const int userAge = static_cast&amp;lt;int&amp;gt;(ls[&amp;quot;UserInfo&amp;quot;][&amp;quot;Age&amp;quot;].value().asNumber());&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;const bool userLikesLargeIcons = ls[&amp;quot;UserInfo&amp;quot;][&amp;quot;LikesLargeIcons&amp;quot;].asBoolean();&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;const int winWidth = static_cast&amp;lt;int&amp;gt;(ls[&amp;quot;WindowSize&amp;quot;][1].value().asNumber());&lt;/blockquote&gt;
&lt;blockquote&gt;const int winHeight = static_cast&amp;lt;int&amp;gt;(ls[&amp;quot;WindowSize&amp;quot;][2].value().asNumber());&lt;/blockquote&gt;
&lt;p&gt;Вызовы функций value(), asNumber() и asString() выглядят немного громоздко, но это совсем не является недостатком (не забудем, что переменные в Lua не являются типизированными, так что из одной и той же переменной можно получить как, скажем, строку, так и число, если &lt;em&gt;преобразование &lt;/em&gt;позволяет {на самом деле типы есть, просто они спрятаны от пользователя [вспоминаем VARIANT]}). Перегружены все операторы для основных типов С++, поддерживаемых Lua, чтобы пользователи библиотеки могли писать нечто подобное.&lt;/p&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;if (ls[&amp;quot;UserInfo&amp;quot;][&amp;quot;LikesLargeIcons&amp;quot;])&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;{&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //...&lt;br /&gt;}&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;if (ls[&amp;quot;FavoriteColor&amp;quot;] != &amp;quot;blue&amp;quot;)&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; &amp;quot;You have bad taste for colors&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Вы могли заметить, чтов файле config.lua была определена функция. Она может быть вызвана из С++ без особых затруднений. Однако есть один важный момент. Функции в Lua могут возвращать произвольное количество значений. Поэтому возвращаемым значением будет объект класса &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/namespaceDiluculum.html#42c98ce88a934306768ba5b0ab3e0bf0" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum::LuaValueList&lt;/font&gt;&lt;/a&gt;. Код, приведенный ниже, показывает как вызывается Lua-функция из С++.&lt;/p&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;Diluculum::LuaValueList ret = ls[&amp;quot;EmphasizeFunc&amp;quot;](&amp;quot;String to be emphasized&amp;quot;);&lt;/blockquote&gt;
&lt;blockquote&gt;cout &amp;lt;&amp;lt; ret[0].asString() &amp;lt;&amp;lt; endl;&lt;/blockquote&gt;
&lt;p style="MARGIN-BOTTOM:0cm;"&gt;Заметьте, что никакого вызова функции value() здесь не требуется. Вызовы Lua-функции из С++ уже возвращают значения (список объектов класса Diluculum::LuaValue), а не переменные (Diluculum::LuaVariable), из которых еще нужно получать значения (как следствие, нетипизированное использование значений в этом случае повлечет LuaException).&lt;/p&gt;
&lt;p&gt;Перегрузки оператора operator[], которые определены и используются в библиотеке, позволяют записывать значения в Lua-переменные (имеется доступ на запить в Lua State). Можно определять новые переменные из кода на С++. Эта функциональность, конечно, не будет полезной, когда Lua используется, как конфигурационный язык, но все таки это иногда бывает полезным. Код, приведенный ниже, показывает как это делается.&lt;/p&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;ls[&amp;quot;newNumber&amp;quot;] = -123.456;&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;ls[&amp;quot;newString&amp;quot;] = &amp;quot;Ahhh!&amp;quot;;&lt;/blockquote&gt;
&lt;blockquote&gt;ls[&amp;quot;FavoritePiApproximation&amp;quot;] = 3.14159265;&lt;/blockquote&gt;
&lt;p style="MARGIN-BOTTOM:0cm;"&gt;&lt;strong&gt;&lt;i&gt;Обертки для С++ функций&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Прежде всего, если так случилось что у нас есть lua_CFunction (Lua-функция, как она определяется в Lua API для С), мы можем попросту присвоить объекту &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/classDiluculum_1_1LuaState.html" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum::LuaState&lt;/font&gt;&lt;/a&gt; это значение, как показывается ниже.&lt;/p&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;int aLuaCFunction(lua_State * ls)&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;{&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //...&lt;br /&gt;}&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;//...&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;// Create a Lua state and register the function there&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;Diluculum::LuaState ls;&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;ls[&amp;quot;Func&amp;quot;] = aLuaCFunction;&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;//Call the function from Lua&lt;/blockquote&gt;
&lt;blockquote&gt;ls.&lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/classDiluculum_1_1LuaState.html#b12ccabf55443f96eb2c74676a3c8045" target="_blank"&gt;&lt;font color="#000080"&gt;doString&lt;/font&gt;&lt;/a&gt;(&amp;quot;Func(1, 2, 3, &amp;#39;four&amp;#39;)&amp;quot;);&lt;/blockquote&gt;
&lt;p&gt;Присваивание значений объекту типа lua_CFunction может вызвать нарушения доступа с использованием lua_State*, и может быть не совсем тем, что Вам необходимо (я бы сказал, что подобное использование противоречит принципу инкапсуляции ООП). Поэтому Diluculum позволяет создавать lua_CFunction автоматически, если ей подготовить функцию на С++, принимающую в качестве параметра и возвращающую в качестве значения объект класса Diluculum::LuaValueList (инкапсуляция списка Lua-значений). Затем такая функция должна быть зарегистрирована в объекте &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/classDiluculum_1_1LuaState.html" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum::LuaState&lt;/font&gt;&lt;/a&gt;, как показано ниже.&lt;/p&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;#include &amp;lt;&lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/LuaWrappers_8hpp.html" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum/LuaWrappers.hpp&lt;/font&gt;&lt;/a&gt;&amp;gt;&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;using namespace Diluculum;&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;//...&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;/* In Lua, this will take one number parameter and return three numbers, which are equal the parameter, two times the parameter and three times the parameter. Not very useful, uh? */&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;LuaVauleList MyFunction(const LuaValueList &amp;amp; params)&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;{&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( (params.size() != 1) || (params[0].type() != LUA_TNUMBER) )&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw LuaError(&amp;quot;Bad parameters&amp;quot;);&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LuaValueList ret;&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; double dVal = params[0].asNumber();&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret.push_back(dVal);&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret.push_back(dVal * 2);&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret.push_back(dVal * 3);&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ret;&lt;br /&gt;}&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;// Create a &amp;#39;lua_CFunction&amp;#39;&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;DILUCULUM_WRAP_FUNCTION(MyFunction);&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;//...&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;// Create&amp;nbsp;Lua State and register the function.&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;LuaState ls;&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;ls[&amp;quot;MyFunction&amp;quot;]&amp;nbsp;= DILUCULUM_WRAPPER_FUNCTION(MyFunction);&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;// Now &amp;#39;MyFunction&amp;#39; can be called from Lua&lt;/blockquote&gt;
&lt;blockquote&gt;ls.doString(&amp;quot;a, b, c&amp;nbsp;= MyFunction(4.5)&amp;quot;);&lt;/blockquote&gt;
&lt;p style="MARGIN-BOTTOM:0cm;"&gt;Тут есть один важный момент в том, что выбрасывание &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/classDiluculum_1_1LuaError.html" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum::LuaError&lt;/font&gt;&lt;/a&gt; является корректным (я бы сказал, единственно корректным) способом сообщить об ошибочной ситуации наружу из обернутой таким способом функции. Для тех, кто уже знает Lua C API, сообщаем что это исключение обрабатывается и преобразуется в вызов lua_error(). (Тем, кто не знает Lua C API, можно особо не волноваться. Более гадкое, чем Lua C API, лично я встречаю редко [тьфу-тьфу-тьфу, по дереву постучать...]. Этим как раз и объясняется, что все более менее здоровые люди используют Lua через подобные библиотеки).&lt;/p&gt;
&lt;p style="MARGIN-BOTTOM:0cm;"&gt;&lt;strong&gt;&lt;i&gt;Обертки для классов и объектов С++&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="MARGIN-BOTTOM:0cm;"&gt;Diluculum имеет ограниценную поддержку для обертывания классов С++ и их объектов в Lua-совместимые, регистрируя их в Lua State соответствующим образом. Поддержка названа ограниченной, т.к. не поддерживается перенос наследования, например. Т.е. нет переноса объектной ориентированности, грубо говоря. Конструкции могут показаться громоздкими. Однако ж они могут пригодиться в хозяйстве.&lt;/p&gt;
&lt;p&gt;Diluculum не может справиться с произвольным классом. Как и в случае с функциями, классы надо подготовить. Оборачиваемые классы должны подчиняться нескольким правилам для того, чтобы быть использованными через Diluculum. Во-первых, должен существовать конструктор копирования, принимающий &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/namespaceDiluculum.html#42c98ce88a934306768ba5b0ab3e0bf0" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum::LuaValueList&lt;/font&gt;&lt;/a&gt;. Во-вторых, методы которые экспортируются в Lua, должны принимать &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/namespaceDiluculum.html#42c98ce88a934306768ba5b0ab3e0bf0" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum::LuaValueList&lt;/font&gt;&lt;/a&gt; в качестве параметра, а также возвращать объект того же типа. Ниже показан пример корректно обернутого класса.&lt;/p&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;// A class that stores one value. Duh.&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;class ValueBox&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;{&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private:&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/classDiluculum_1_1LuaValue.html" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum::LuaValue&lt;/font&gt;&lt;/a&gt; value_;&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public:&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // The constructor taking a &amp;#39;Diluculum::LuaValueList&amp;#39; parameter.&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ValueBox( const Diluculum::LuaValueList &amp;amp; params)&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (params.size() &amp;gt; 0)&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value_ = params[0];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Stores the value passed as parameter in the box and returns the value previously stored there */&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Diluculum::LuaValueList swap(const Diluculum::LuaValueList &amp;amp; params)&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (params.size() != 1)&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw Diluculum::LuaError(&amp;quot;Exactly one parameter was expected.&amp;quot;);&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Diluculum::LuaValueList ret;&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret.push_back(value_);&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value_ = params[0];&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ret;&lt;/blockquote&gt;
&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;};&lt;/blockquote&gt;
&lt;p&gt;Как и в случае обернутых функций, единственным правильным способом донести об ошибочной ситуации является выброс &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/classDiluculum_1_1LuaError.html" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum::LuaError&lt;/font&gt;&lt;/a&gt;. Класс экспортируется в Lua через использование макросов, подставляющих необходимый код на Lua C API и определяющих некоторые структуры с данными. (Для читателей, интересующихся механизмом преобразования: библиотека создает глобальный объект &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/namespaceDiluculum.html#1e97e3b5307cbc940108ddb8d0e616d9" target="_blank"&gt;&lt;font color="#000080"&gt;Diluculum::LuaValueMap&lt;/font&gt;&lt;/a&gt;, представляющий класс и являющийся метатаблицей для объектов этого класса в Lua). Вот как выглядит регистрация класса на С++.&lt;/p&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/LuaWrappers_8hpp.html#abc543a317b1623f2079f75155eb3a21" target="_blank"&gt;&lt;font color="#000080"&gt;DILUCULUM_BEGIN_CLASS&lt;/font&gt;&lt;/a&gt;(ValueBox);&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/LuaWrappers_8hpp.html#20d9a08f1bbe4a54a2276cd7c2ecdd14" target="_blank"&gt;&lt;font color="#000080"&gt;DILUCULUM_CLASS_METHOD&lt;/font&gt;&lt;/a&gt;(ValueBox, swap);&lt;/blockquote&gt;
&lt;blockquote&gt;DILUCULUM_END_CLASS(ValueBox);&lt;/blockquote&gt;
&lt;p&gt;Имеется только одно использование макроса &lt;a href="http://www.stackedboxes.org/Projects/Diluculum/Documentation/Doxygen/LuaWrappers_8hpp.html#20d9a08f1bbe4a54a2276cd7c2ecdd14" target="_blank"&gt;&lt;font color="#000080"&gt;DILUCULUM_CLASS_METHOD()&lt;/font&gt;&lt;/a&gt;, т.к. в классе, что описан выше, имеется только один экспортируемый в Lua метод. Разумеется, можно добавлять произвольное количество методов. Теперь мы готовы к регистраци этого класса в Lua State, чтобы потом его использовать (это необходимо, иначе Lua &amp;quot;не увидит&amp;quot; Вашего класса, будет писать о синтаксических ошибках). Для этого требуется использовать еще один макрос. После этого объекты обернутого класса могут создаваться из Lua-кода. Код ниже демонстрирует сказанное.&lt;/p&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;Diluculum::LuaState ls;&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;DILUCULUM_REGISTER_CLASS(ls[&amp;quot;ValueBox&amp;quot;], ValueBox);&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;ls.doString(&amp;quot;box = ValueBox.new(3)&amp;quot;);&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;ls.doString(&amp;quot;print(box:swap(&amp;#39;foo&amp;#39;))&amp;quot;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// prints &amp;#39;3&amp;#39;&lt;/blockquote&gt;
&lt;blockquote&gt;ls.doString(&amp;quot;print(box:swap(789.987))&amp;quot;); // prints &amp;#39;foo&amp;#39;&lt;/blockquote&gt;
&lt;p style="MARGIN-BOTTOM:0cm;"&gt;&lt;strong&gt;&lt;i&gt;Управление памятью&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;В Lua имеется сборщик мусора, подобно .NET и Java. Когда объект С++, созданный из Lua, очищается из памяти сборщиком, вызывается его деструктор С++. Таким образом, ресурсы корректно освобождаются (конечно же, в предположении, что программист правильно написал деструктор). Тем не менее, имеется возможность заставить Lua вызвать деструктор явно, чтобы самому управлять процессом очистки. Ниже показывается соответствующий код.&lt;/p&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;Diluculum::LuaState ls;&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;DILUCULUM_REGISTER_CLASS(ls[&amp;quot;ValueBox&amp;quot;], ValueBox);&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;ls.doString(&amp;quot;box = ValueBox.new()&amp;quot;);&lt;/blockquote&gt;
&lt;blockquote style="MARGIN-BOTTOM:0cm;"&gt;// ... use &amp;#39;box&amp;#39; ...&lt;/blockquote&gt;
&lt;blockquote&gt;ls.doString(&amp;quot;box:delete()&amp;quot;);&lt;