C + + Primer Learning notes _104_ special tools and techniques--Nested classes

Source: Internet
Author: User
Tags class definition

Special tools and techniques--Nested classes

There is the ability to define a class within a class, which is nested classes, also known as nested types, unlike the local classes described later . Nested classes are most often used to define run classes.

Nested classes are independent classes and are basically unrelated to their perimeter classes, so the objects of the perimeter class and the nested class are independent of each other. Objects of nested types do not have members defined by the perimeter class, and members of the perimeter class do not have members defined by nested classes.

The name of a nested class is visible in the scope of its perimeter class, but not in the scope of another class scope or defined perimeter class. The name of a nested class will not conflict with a name declared in another scope

Nested classes can have members of the same kind as non-nested classes. Like any other class, nested classes use the access labels to control the access to their members. Members can be declared as public,private , or protected. The perimeter class has no special access to the members of the nested class, and the nested class has no special access to the members of its perimeter class .

a nested class defines a type member in its perimeter class. Like any other member, the perimeter determines this type of access.

Implementation of nested classes

Instance

WillQueueitemclass is set toQueueClass ofPrivatemembers, then,Queueclass (and its friends) can use theQueueitem, butQueueitemclass types are not visible to normal user code. OnceQueueitemclass itself isPrivate, we are able to make its members Publicmember--just haveQueueorQueuefriends can visitQueueitemtype, so you don't have to prevent general program AccessQueueitemmembers. By using reserved wordsstructdefinitionQueueitemmake a member Publicmembers.

New designs such as the following:

Template <typename type>class queue{public:    //...private:    struct queueitem    {        Queueitem (const Type &);        Type item;        Queueitem *next;    };    Queueitem *head;    Queueitem *tail;};

1. A class nested inside a class template is a template

due to queue so its members are also templates , and queueitem queue

each instantiation of the Queue class produces its own Queueitem class with the appropriate template for the type . The mapping between the instantiation of the Queueitem class template and the instantiation of the perimeter Queue class template is one-to-one .

2. Defining members of nested classes

Nested class members that are defined outside their class must be defined in the same scope that defines the perimeter class . A member of a nested class defined outside its class cannot be defined inside a perimeter class, and members of a nested class are not members of a perimeter class .

the constructor of the Queueitem class is not a member of the queue class, so it cannot be defined anywhere in the queue class definition Body .

Template <class Type>queue<type>::queueitem::queueitem (const Type &t): item (t), next (0) {}

Because Queue and queueitem are templates , This constructor is also a template .

3. Defining nested classes outside the perimeter class

Nested classes typically support the implementation details of the perimeter class. We may want to prevent users of the perimeter class from seeing the implementation code for the nested class.

For example, we may want to place the definition of the queueitem class in its own file, which we can include in the implementation file of the Queue class and its members. Just as members of a nested class can be defined outside the class definition body, we can also define the entire nested class outside the perimeter class definition body:

Template <typename type>class queue{public:    //...private:    struct queueitem;    Queueitem *head;    Queueitem *tail;}; Template <class type>struct queue<type>::queueitem{    queueitem (const Type &t): item (t), next (0) {}    Type Item;    Queueitem *next;};

Note that we have to declare the queueitem class inside the Queue class body .

[ caution ]

Before you see the actual definition of a nested class defined outside the class definition body, the class is not completely typed , and the application uses all of the general restrictions of the non-full type.

4. Nested class static member definitions

Assuming that the Queueitem class declares a static member , Its definition also needs to be placed in the outer scope , assuming that the Queueitem There is a static member :

Template <class Type>int queue<type>::queueitem::static_mem = 1024;

5. Using members of the perimeter class

There is no connection between an object of a perimeter scope and an object of its nested type

Template <typename type>void Queue<type>::p op () {    Queueitem *q = head;    Head = head Next;    Delete q;}

an object of type Queue does not have a name of item or next member . Queue function members of a class can use the Head and the Tail members (they are points to Queueitem object) to get those Queueitem members.

6. Use static members or other types of members

A nested class can directly reference a static member of a perimeter class, a type name and an enumeration member [ with the local class described later ]. however , References A type name or static member outside the scope of a perimeter class that requires a scope determination operator .

7. Instantiation of nested templates

When you instantiate a perimeter class template, you are not actively instantiating the nested classes of the class template yourself . As with any member function, nested classes are instantiated only when the nested class itself is used in cases where the full class type is required . For example, like



This definition, the Queue template is instantiated with the int type , but the queueitem<int> type is not instantiated . members head and tail are pointers to queueitem<int>, and there is no need to instantiate queueitem<int> to define a pointer to that class.

Only when using queueitem<int> - only when the member function of the queue<int> class the queueitem<int> class is instantiated only when head and tail are dereferenced .

Name lookup in nested class scopes

When processing a class member declaration , the name used must appear before use ; when processing When defined , the entire nested class and the perimeter class are in scope .

Class Outer{public:    struct Inner    {        void process (const Outer &);    OK        Inner2 val;     Error    };    struct Inner2    {public    :        Inner2 (int i = 0): Val (i) {}        void process (const Outer &out)  //ok< c23/>{            Out.handle ();        }    Private:        int val;    };    void handle () const;};

[ description ]

compiler first handles  OUTER&NBSP, and   . The name  OUTER&NBSP; as   inner::p rocess  PROCESS&NBSP; that class is still incomplete, but " is a reference , So this use is correct.  

The declaration of the data member Inner::val is wrong, and the Inner2 type has not been seen.

the declarations in Inner2 seem to have no problem -they mostly only use built-in type int. The only exception is the member function process, which determines that the shape of the Outer is not completely typed . Because its shape is a reference, it does not matter if the Outer is not completely typed.

The compiler handles the definition of constructors and process members until you see the rest of the declarations in the perimeter class . The declaration of the Outer class is placed in the scope of the handle of the function.

When the compiler looks forInner2class, the name of the definition used in theInner2Classes andOuterall the names in the class are in scope. the use of Val (before the declaration of today's Val ) is correct: Bind the reference to a data member in the Inner2 class[I don't understand what this paragraph means .%>_<%]。 SameInner2::p rocessin the member function bodyOuterClass ofHandleAre also used correctly,when compiling members of the Inner2 class, the entire Outer class is in scope。

Using scope operators to control name lookups

The ability to use the scope operator to access the global version number of handle :

        void process (const Outer &out)        {            :: Hadle (out);        }

C + + Primer Learning notes _104_ special tools and techniques--Nested classes

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.