logo
 Pokrewne IndeksE Nesbit The Five Children OmnibusThe Beck Brothers 2 Sebastian Andria Large03.śąydowskie dziejeCalling the Show J.A. RockFaria Laurie A Niebieski pśÂ‚omieśÂ„ na koszmary(Ebook German Erotik) Flirt Kurs, Vom Anbaggern Zum Flirten68. Carlos Fuentes La Silla del ÁguilaBlaylock James P. Maszyna lorda KelvinaAleister Crowley AtlantydaLong Julie Anne Pennyroyal Green 06 Gra o markiza
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • apo.htw.pl



  • [ Pobierz całość w formacie PDF ]

    instance thereof. There are several features for manipulating the state of a class rather
    than the state of individual objects. These features are discussed in the following sections.
    Static Data Members
    A static member is shared by all instances of its class. For that reason, it is sometimes
    termed a class variable. Static members are useful in synchronization objects. For
    example, a file lock can be implemented using a static data member. An object that is
    trying to access this file has to check first whether the file is being processed by another
    user. If the file is available, the object turns the flag on and user can process the file
    safely. Other users are not allowed to access the file until the flag is reset to false. When
    the object that is processing the file is finished, it has to turn off the flag, enabling another
    object to access it.
    class fileProc
    {
    private:
    FILE *p;
    static bool Locked;
    public:
    //...
    bool isLocked () const;
    //...
    };
    bool fileProc::Locked;
    Static Member Functions
    A static member function in a class can access only other static members of its class..
    Unlike ordinary member functions, a static member function can be invoked even when
    no object instance exists. For example
    class stat
    {
    private:
    int num;
    public:
    stat(int n = 0) {num=n;}
    static void print() {cout
    };
    int main()
    {
    stat::print(); //no object instance required
    stat s(1);
    s.print();//still, a static member function can be called from an
    object
    return 0;
    }
    Static members are used in the following cases:
    " When all other data members of an object are also static
    " When the function does not depend on any other object member (like print(), in
    the previous example)
    " As a wrapper of a global function
    A Pointer to Member Cannot Refer To a Static Member Function
    It is illegal to assign the address of a static class member to a pointer to member.
    However, you can take the address of a static member function of a class and treat it as if
    it were an ordinary function. For example
    class A
    {
    public:
    static void f();
    };
    int main()
    {
    void (*p) () = &A::f; //OK, ordinary pointer to function
    }
    You can do this because a static member function is essentially an ordinary function,
    which doesn't take an implicit this argument.
    Defining a Class Constant
    When you need a constant integer member in a class, the easiest way to create one is by
    using a const static member of an integral type; unlike other static data members,
    such a member can be initialized within the class body (see also Chapter 2, "Standard
    Briefing: The Latest Addenda to ANSI/ISO C++"). For example
    class vector
    {
    private:
    int v_size;
    const static int MAX 1024; //a single MAX is shared by all vector
    objects
    char *p;
    public:
    vector() {p = new char[MAX]; }
    vector( int size)
    {
    if (size
    p = new char[size] ;
    else
    p = new char[MAX];
    }
    };
    Designing Class Hierarchies
    After identifying a set of potential classes that might be required for the application, it is
    important to correctly identify the interactions and relationships among the classes to
    specify inheritance, containment, and ownership. The design of class hierarchies, as
    opposed to designing concrete types, requires additional considerations that are discussed
    in this section.
    Private Data Members Are Preferable To Protected Ones
    Data members of a class are usually a part of its implementation. They can be replaced
    when the internal implementation of the class is changed; therefore, they need to be
    hidden from other classes. If derived classes need to access these data members, they
    need to use accessor methods instead of directly accessing data members of a base class.
    Consequently, no modification is required for derived classes when a change is made in
    the base class.
    Here's an example:
    class Date
    {
    private:
    int d,m,y //how a date is represented is an implementation detail
    public:
    int Day() const {return d; }
    };
    class DateTime : public Date
    {
    private:
    int hthiss;
    int minutes;
    int seconds;
    public:
    //...additional member functions
    };
    Now assume that class Date is used mostly on display devices, so it has to supply some
    method of converting its d,m,y members into a displayable string. In order to enhance
    performance, a design modification is made: Instead of the three integers, a single
    string now holds the date representation. Had class DateTime relied on the internal
    implementation of Date, it would have had to be modified as well. But because it can
    access Date's data members only through access methods, all that is required is a small
    change in the Date::Day() member function. Please note that accessor methods are
    usually inlined anyway, so their use does not incur additional runtime overhead.
    Declaring Virtual Base Class Destructors
    A base class needs to have its destructor declared virtual. In doing so, you ensure that
    the correct destructor is always called, even in the following case:
    class Base
    {
    private:
    char *p;
    public:
    Base() { p = new char [200]; }
    ~ Base () {delete [] p; } //non virtual destructor, bad
    };
    class Derived : public Base
    {
    private:
    char *q;
    public:
    Derived() { q = new char[300]; }
    ~Derived() { delete [] q; }
    //...
    };
    void destroy (Base & b)
    {
    delete &b;
    }
    int main()
    {
    Base *pb = new Derived(); //200 + 300 bytes allocated
    //... meddle with pb
    destroy (*pb); //OOPS! only the destructor of Base is called [ Pobierz całość w formacie PDF ]

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • aureola.keep.pl