Чтение онлайн

ЖАНРЫ

Стандарты программирования на С++. 101 правило и рекомендация

Александреску Андрей

Шрифт:

Размер имеет значение. При замене указателя на

Derived
указателем на
Base
компилятор точно знает, как следует подкорректировать (при необходимости) указатель, поскольку у него есть достаточное количество информации об обоих классах. Однако при выполнении арифметических операций над указателем
p
на
Base
компилятор вычисляет
p[n]
как
*(p+n*sizeof(Base)
), таким образом полагаясь на то, что объекты, находящиеся в памяти, — это объекты типа
Base
, а не некоторого производного типа, который может иметь другой размер.
Представляете, какая ерунда может получиться при работе с массивом объектов
Derived
, если вы преобразуете указатель на начало этого массива в указатель типа
Base*
(что компилятор вполне допускает), а затем примените арифметические операции к этому указателю (что компилятор также пропустит, не моргнув глазом)!

Такие неприятности представляют собой результат взаимодействия двух концепций — заменимости указателей на производный класс указателями на базовый класс, и унаследованной от С арифметикой указателей, которая считает указатели мономорфными и использует при вычислениях только статическую информацию.

Для хранения массива полиморфных объектов вам нужен массив (а еще лучше — контейнер; см. рекомендацию 77) указателей на базовый класс (например, обычных указателей или, что еще лучше, интеллектуальных указателей

shared_ptr
; см. рекомендацию 79). Тогда каждый указатель массива указывает на полиморфный объект, скорее всего, объект в динамически выделенной памяти. (Если вы хотите обеспечить интерфейс контейнера полиморфных объектов, вам надо инкапсулировать весь массив и предоставить соответствующий полиморфный интерфейс для выполнения итераций.)

Кстати, одна из причин, по которой в интерфейсах следует предпочитать ссылки указателям, заключается в том, чтобы было совершенно очевидно, что речь идет только об одном объекте, а не о массиве объектов.

Ссылки

[C++TR104] • [Dewhurst03] §33, §89 • [Sutter00] §36 • [Meyers96] §3

Список литературы

Примечание: для удобства читателей весь список литературы доступен по адресу http://www.gotw.ca/publications/c++cs/bibliography.htm

Ссылки, выделенные полужирным шрифтом (например, [Abrahams96]), представляют собой гиперссылки в приведенной выше странице.

[Abelson96] Abelson H. and Sussman G. J. Structure and Interpretation of Computer Programs (2nd Edition) (MIT Press, 1996).

[Abrahams96] Abrahams D. Exception Safety in STLport. STLport website, 1996.

[Abrahams01a] Abrahams D. Exception Safety in Generic Components, in Jazayeri M., Loos R., Musser D. (eds.), Generic Programming: International Seminar on Generic Programming, Dagstuhl Castle, Germany, April/May 1998, Selected Papers. Lecture Notes in Computer Science 1766 (Springer, 2001).

[Abrahams01b] Abrahams D. Error and Exception Handling. [Boost] website, 2001.

[Alexandrescu00a] Alexandrescu A. Traits: The else-if-then of Types. С++ Report, 12(4), April 2000.

[Alexandrescu00b] Alexandrescu A. Traits on Steroids. С++ Report, 12(6), June 2000.

[Alexandrescu00c] Alexandrescu A. and Marginean P. Change the Way You Write Exception-Safe Code — Forever. C/C++ Users Journal, 18(12), December 2000.

[Alexandrescu01] Alexandrescu A. Modern С++ Design. Addison-Wesley, 2001.

Перевод:

Александреску А. Современное проектирование на С++. Серия С++ In-Depth, т.3. — М.: Издательский дом "Вильямс", 2002.

[Alexandrescu01a] Alexandrescu A. A Policy-Based basic_string Implementation. C/C++ Users Journal, 19(6), June 2001.

[Alexandrescu02a] Alexandrescu A. Multithreading and the С++ Type System. InformIT website, February 2002.

[Alexandrescu02b] Alexandrescu A. "Discriminated Unions (I)," "... (II)," and "... (III)". C/C++ Users Journal, 20(4,6,8), April/June/August 2002.

[Alexandrescu03a] Alexandrescu A. Move Constructors. C/C++ Users Journal, 21(2), February 2003.

[Alexandrescu03b] Alexandrescu A. Assertions. C/C++ Users Journal, 21(4), April 2003.

[Alexandrescu03c] Alexandrescu A. and Marginean P. Enforcements. C/C++ Users Journal, 21(6), June 2003.

[Alexandrescu03d] Alexandrescu A. and Held D. Smart Pointers Reloaded. C/C++ Users Journal, 21(10), October 2003.

[Alexandrescu04] Alexandrescu A. Lock-Free Data Structures. C/C++ Users Journal, 22(10), October 2004.

[Allison98] Allison С. С & С++ Code Capsules. Prentice Hall, 1998.

[Austern99] Austern M. H. Generic Programming and the STL. Addison-Wesley, 1999.

[Barton94] Barton J. and Nackman L. Scientific and Engineering С++. Addison-Wesley, 1994.

[Bentley00] Bentley J. Programming Pearls (2nd Edition). Addison-Wesley, 2000.

Перевод: Бентли Дж. Жемчужины программирования. Второе издание. — СПб.: Питер, 2002.

[BetterSCM] Web-узел Better SCM Initiative.

[Boost] С++ Boost.

[BoostLRG] Boost Library Requirements and Guidelines. (Web-узел Boost).

[Brooks95] Brooks F. The Mythical Man-Month. Addison-Wesley, 1975; reprinted with corrections in 1995.

[Butenhof97] Butenhof D. Programming with POSIX Threads. Addison-Wesley, 1997.

[Cargill92] Cargill T. С++ Programming Style. Addison-Wesley, 1992.

[C90] ISO/IEC 9899:1990(E), Programming Languages — C (ISO C90 and ANSI C89 Standard).

[C99] ISO/IEC 9899:1999(E), Programming Languages — C (revised ISO and ANSI C99 Standard).

[C++98] ISO/IEC 14882:1998(E), Programming Languages — С++ (ISO and ANSI С++ Standard).

[C++03] ISO/IEC 14882:2003(E), Programming Languages — С++ (updated ISO and ANSI С++ Standard including the contents of [C++98] plus errata corrections).

[C++TR104] ISO/IEC JTC1/SC22/WG21/N1711. (Draft) Technical Report on Standard Library Extensions (ISO С++ committee working document, November 2004). Близкий к окончанию черновик с расширениями стандартной библиотеки С++, включая

shared_ptr
.

[Cline99] Cline М., Lomow G., and Girou M. С++ FAQs (2nd Edition). Addison-Wesley, 1999.

Поделиться с друзьями: