Читаем C++ Primer Plus полностью

I am a magnificent class!!!

I hold the character P and the integer 52!

Yes, you're really magnificent.

Now processing type Superb.

I am a superb class!!

I hold the superb value of 37!

Now processing type Grand.

I am a grand class!

Now processing type Superb.

I am a superb class!!

I hold the superb value of 18!

Now processing type Grand.

I am a grand class!

As with the preceding example, the exact output will vary from run to run because the program uses rand() to select types. Also some compilers may provide different output when name() is called, for example, 5Grand instead of Grand.

Misusing RTTI

RTTI has many vocal critics within the C++ community. They view RTTI as unnecessary, a potential source of program inefficiency, and a possible contributor to bad programming practices. Without delving into the debate over RTTI, let’s look at the sort of programming that you should avoid.

Consider the core of Listing 15.17:

Grand * pg;

Superb * ps;

for (int i = 0; i < 5; i++)

{

    pg = GetOne();

    pg->Speak();

    if( ps = dynamic_cast(pg))

         ps->Say();

}

By using typeid and ignoring dynamic_cast and virtual functions, you can rewrite this code as follows:

Grand * pg;

Superb * ps;

Magnificent * pm;

for (int i = 0; i < 5; i++)

{

    pg = GetOne();

    if (typeid(Magnificent) == typeid(*pg))

    {

        pm = (Magnificent *) pg;

        pm->Speak();

        pm->Say();

    }

    else if (typeid(Superb) == typeid(*pg))

    {

        ps = (Superb *) pg;

        ps->Speak();

        ps->Say();

    }

    else

        pg->Speak();

}

Not only is this uglier and longer than the original, it has the serious flaw of naming each class explicitly. Suppose, for example, that you find it necessary to derive an Insufferable class from the Magnificent class. And suppose the new class redefines Speak() and Say(). With the version that uses typeid to test explicitly for each type, you would have to modify the for loop code, adding a new else if section. The original version, however, requires no changes at all. The following statement works for all classes derived from Grand:

pg->Speak();

And this statement works for all classes derived from Superb:

if( ps = dynamic_cast(pg))

      ps->Say();

Tip

If you find yourself using typeid in an extended series of if else statements, you should check whether you should instead use virtual functions and dynamic_cast.

Type Cast Operators

The C type cast operator, in Bjarne Stroustrup’s view, is too lax. For example, consider the following:

struct Data

{

    double data[200];

};

struct Junk

{

    int junk[100];

};

Data d = {2.5e33, 3.5e-19, 20.2e32};

char * pch = (char *) (&d);   // type cast #1 – convert to string

char ch = char (&d);          // type cast #2 - convert address to a char

Junk * pj = (Junk *) (&d);    // type cast #3 - convert to Junk pointer

First, which of these three type casts makes any sense? Unless you resort to the implausible, none of them make much sense. Second, which of these three type casts are allowed? In C, all of them are. Stroustrup’s response to this laxity was to tighten up what is allowable for a general type cast and to add four type cast operators that provide more discipline for the casting process:

dynamic_cast

const_cast

static_cast

reinterpret_cast

Instead of using a general type cast, you can select an operator that is suited to a particular purpose. This documents the intended reason for the type cast and gives the compiler a chance to check that you did what you thought you did.

You’ve already seen the dynamic_cast operator. To summarize, suppose High and Low are two classes, that ph is type High *, and that pl is type Low *. Then the following statement assigns a Low * pointer to pl only if Low is an accessible base class (direct or indirect) to High:

pl = dynamic_cast ph;

Otherwise, the statement assigns the null pointer to pl. In general, the operator has this syntax:

dynamic_cast < type-name > (expression)

The purpose of this operator is to allow upcasts within a class hierarchy (such type casts being safe because of the is-a relationship) and to disallow other casts.

The const_cast operator is for making a type cast with the sole purpose of changing whether a value is const or volatile. It has the same syntax as the dynamic_cast operator:

const_cast < type-name > (expression)

The result of making such a type cast is an error if any other aspect of the type is altered. That is, type_name and expression must be of the same type, except that they can differ in the presence or absence of const or volatile. Again, suppose High and Low are two classes:

High bar;

const High * pbar = &bar

    ...

High * pb = const_cast (pbar);    // valid

const Low * pl = const_cast (pbar);      // invalid

The first type cast makes *pb a pointer that can be used to alter the value of the bar object; it removes the const label. The second type cast is invalid because it attempts to change the type from const High * to const Low *.

Перейти на страницу:

Все книги серии Developer's Library

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных