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

Looking at the code for the last example, you may notice that most of the Remote methods are implemented by using the public interface for the Tv class. This means that those methods don’t really need friend status. Indeed, the only Remote method that accesses a private Tv member directly is Remote::set_chan(), so that’s the only method that needs to be a friend. You do have the option of making just selected class members friends to another class rather than making the entire class a friend, but that’s a bit more awkward. You need to be careful about the order in which you arrange the various declarations and definitions. Let’s look at why.

The way to make Remote::set_chan() a friend to the Tv class is to declare it as a friend in the Tv class declaration:

class Tv

{

    friend void Remote::set_chan(Tv & t, int c);

    ...

};

However, for the compiler to process this statement, it needs to have already seen the Remote definition. Otherwise, it won’t know that Remote is a class and that set_chan() is a method of that class. This suggests putting the Remote definition above the Tv definition. But the fact that Remote methods mention Tv objects means that the Tv definition should appear above the Remote definition. Part of the way around the circular dependence is to use a forward declaration. To do so, you insert the following statement above the Remote definition:

class Tv;              // forward declaration

This provides the following arrangement:

class Tv;  // forward declaration

class Remote { ... };

class Tv { ... };

Could you use the following arrangement instead?

class Remote;          // forward declaration

class Tv { ... };

class Remote { ... };

The answer is no. The reason, as mentioned earlier, is that when the compiler sees that a Remote method is declared as a friend in the Tv class declaration, the compiler needs to have already viewed the declaration of the Remote class in general and of the set_chan() method in particular.

Another difficulty remains. In Listing 15.1, the Remote declaration contains inline code such as the following:

void onoff(Tv & t) { t.onoff(); }

Because this calls a Tv method, the compiler needs to have seen the Tv class declaration at this point so that it knows what methods Tv has. But as you’ve seen, that declaration necessarily follows the Remote declaration. The solution to this problem is to restrict Remote to method declarations and to place the actual definitions after the Tv class. This leads to the following ordering:

class Tv;               // forward declaration

class Remote { ... };     // Tv-using methods as prototypes only

class Tv { ... };

// put Remote method definitions here

The Remote prototypes look like this:

void onoff(Tv & t);

All the compiler needs to know when inspecting this prototype is that Tv is a class, and the forward declaration supplies that information. By the time the compiler reaches the actual method definitions, it has already read the Tv class declaration and has the added information needed to compile those methods. By using the inline keyword in the method definitions, you can still make the methods inline methods. Listing 15.4 shows the revised header file.

Listing 15.4. tvfm.h

// tvfm.h -- Tv and Remote classes using a friend member

#ifndef TVFM_H_

#define TVFM_H_

class Tv;                       // forward declaration

class Remote

{

public:

    enum State{Off, On};

    enum {MinVal,MaxVal = 20};

    enum {Antenna, Cable};

    enum {TV, DVD};

private:

    int mode;

public:

    Remote(int m = TV) : mode(m) {}

    bool volup(Tv & t);         // prototype only

    bool voldown(Tv & t);

    void onoff(Tv & t) ;

    void chanup(Tv & t) ;

    void chandown(Tv & t) ;

    void set_mode(Tv & t) ;

    void set_input(Tv & t);

    void set_chan(Tv & t, int c);

};

class Tv

{

public:

    friend void Remote::set_chan(Tv & t, int c);

    enum State{Off, On};

    enum {MinVal,MaxVal = 20};

    enum {Antenna, Cable};

    enum {TV, DVD};

    Tv(int s = Off, int mc = 125) : state(s), volume(5),

        maxchannel(mc), channel(2), mode(Cable), input(TV) {}

    void onoff() {state = (state == On)? Off : On;}

    bool ison() const {return state == On;}

    bool volup();

    bool voldown();

    void chanup();

    void chandown();

    void set_mode() {mode = (mode == Antenna)? Cable : Antenna;}

    void set_input() {input = (input == TV)? DVD : TV;}

    void settings() const;

private:

    int state;

    int volume;

    int maxchannel;

    int channel;

    int mode;

    int input;

};

// Remote methods as inline functions

inline bool Remote::volup(Tv & t) { return t.volup();}

inline bool Remote::voldown(Tv & t) { return t.voldown();}

inline void Remote::onoff(Tv & t) { t.onoff(); }

inline void Remote::chanup(Tv & t) {t.chanup();}

inline void Remote::chandown(Tv & t) {t.chandown();}

inline void Remote::set_mode(Tv & t) {t.set_mode();}

inline void Remote::set_input(Tv & t) {t.set_input();}

inline void Remote::set_chan(Tv & t, int c) {t.channel = c;}

 #endif

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

Все книги серии 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.

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

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