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

        balance -= amt;


    }


    else


        cout << "Credit limit exceeded. Transaction cancelled.\n";


}

Using protected data members may simplify writing the code, but it has a design defect. For example, continuing with the BrassPlus example, if balance were protected, you could write code like this:

void BrassPlus::Reset(double amt)


{


    balance = amt;


}

The Brass class was designed so that the Deposit() and Withdraw() interface provides the only means for altering balance. But the Reset() method essentially makes balance a public variable as far as BrassPlus objects are concerned, ignoring, for example, the safeguards found in Withdraw().


Caution

You should prefer private to protected access control for class data members, and you should use base-class methods to provide derived classes access to base-class data.


However, protected access control can be quite useful for member functions, giving derived classes access to internal functions that are not available publicly.

Abstract Base Classes

So far you’ve seen simple inheritance and the more intricate polymorphic inheritance. The next step in increasing sophistication is the abstract base class (ABC). Let’s look at some programming situations that provide the background for ABCs.

Sometimes applying the is-a rule is not as simple as it might appear. Suppose, for example, you are developing a graphics program that is supposed to represent, among other things, circles and ellipses. A circle is a special case of an ellipse: It’s an ellipse whose long axis is the same as its short axis. Therefore, all circles are ellipses, and it is tempting to derive a Circle class from an Ellipse class. But when you get to the details, you may find problems.

To see this, first consider what you might include as part of an Ellipse class. Data members could include the coordinates of the center of the ellipse, the semimajor axis (half the long diameter), the semiminor axis (half the short diameter), and an orientation angle that gives the angle from the horizontal coordinate axis to the semimajor axis. Also the class could include methods to move the ellipse, to return the area of the ellipse, to rotate the ellipse, and to scale the semimajor and semiminor axes:

class Ellipse


{


private:


    double x;     // x-coordinate of the ellipse's center


    double y;     // y-coordinate of the ellipse's center


    double a;     // semimajor axis


    double b;     // semiminor axis


    double angle; // orientation angle in degrees


    ...


public:


    ...


    void Move(int nx, ny) { x = nx; y = ny; }


    virtual double Area() const { return 3.14159 * a * b; }


    virtual void Rotate(double nang) { angle += nang; }


    virtual void Scale(double sa, double sb)  { a *= sa; b *= sb; }


    ...


};

Now suppose you derive a Circle class from the Ellipse class:

class Circle : public Ellipse


{


    ...


};

Although a circle is an ellipse, this derivation is awkward. For example, a circle needs only a single value, its radius, to describe its size and shape instead of having a semimajor axis (a) and semiminor axis (b). The Circle constructors can take care of that by assigning the same value to both the a and b members, but then you have redundant representation of the same information. The angle parameter and the Rotate() method don’t really make sense for a circle, and the Scale() method, as it stands, can change a circle to a non-circle by scaling the two axes differently. You can try fixing things with tricks, such as putting a redefined Rotate() method in the private section of the Circle class so that Rotate() can’t be used publicly with a circle, but, on the whole, it seems simpler to define a Circle class without using inheritance:

class Circle      // no inheritance


{


private:


    double x;     // x-coordinate of the circle's center


    double y;     // y-coordinate of the circle's center


    double r;     // radius


    ...


public:


    ...


    void Move(int nx, ny) { x = nx; y = ny; }


    double Area() const { return 3.14159 * r * r; }


    void Scale(double sr)  { r *= sr; }


    ...


};

Now the class has only the members it needs. Yet this solution also seems weak. The Circle and Ellipse classes have a lot in common, but defining them separately ignores that fact.

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

Все книги серии 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.2
1С: Управление торговлей 8.2

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

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

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