The road to coding--re-learning C + + (4): Defining a correct class

Source: Internet
Author: User

We can all define a class, but how to define a correct class is a question that needs our deep understanding. The parent of C + + has said that the basic idea of defining a new type is that it is not necessary to implement a class (the layout details that are used to store objects of that type) and the properties that are critical to the proper use of the class (member functions that access the data) are designed separately. The best way to achieve this distinction is to provide a specific surface interface, and all calls to the internal data structures and internal maintenance of the class pass through the surface interface.

1. How does the class define

(1) First we have to understand that, to create an object, the constructor puts the member variables in the heap (except for the static variable, the static variable is placed in the global variable area), and the parameters of all member functions are placed on the stack. In particular, statically static member variables, which are part of a class, are not part of the object of each class, so there is only one in each class, not defined in the header file when the static member variable is defined, so that other files contain the header file multiple times, The assignment of a static member variable is performed several times, which is not allowed. Also, when declaring static static member variables in a class, you need to add the "static" keyword, and do not add the "static" keyword when you define it.

(2) When a member function in a class is logically, he should be const, but the function still needs to modify some member variables, we know that the two are contradictory, but there is no workaround? Yes, that is "mutable", which means that this member can be stored in a way that can be updated, even if it is a const member variable.

classdate{mutableBOOLCache_valid; MutablestringCache; voidCompute_cache_value ()Const;//populating the Cache Public:    stringString_rep ()Const;//string Representation};stringDate::string_rep ()Const{    if(!cache_valid)        {Compute_cache_value (); Cache_valid=true; }    returnCache;}

When we need an object that is logically const but actually needs to be modified, the better option is to put the data that needs to be modified into another separate object.

structcache{BOOLvalid; stringRep;};classdate{Cache*C; voidCompute_cache_value ()Const; Public:    stringString_rep ()Const;}stringDate::string_rep ()Const{    if(!cvalid)        {Compute_cache_value (); C-valid =true; }    returnC-Rep;}

(3) in C + +, defined functions within a class are inline functions, but for clarity of code, it is recommended that the inline function be defined immediately after the class definition.

class date{public:    intconst;     // ... Private :     int D, M, y;     // ...  intconst{    return  D;}

(4) The following is an efficient user-defined date type, which is worth our reference:

classdate{ Public://public Interface    enumMonth {Jan =1, Feb, Mar, Apr, May, June, Jul, April, Sep, oct,nov,dec}; classbad_date{}//exception class, for exception reporting errorsDate (intDD =0, Month Mon = month (0),intyy =0);//0 is the defaultA value that describes how the constructor is initialized. //to view the functions of date:    intDay ()Const; Month month ()Const; intYear ()Const; stringString_rep ()Const; voidChar_rep (CharS[])Const;//Modifying the function of datedate& Add_day (intN); Date& Add_month (intN); Date& Add_year (intn);Private:    intD,m,y; StaticDate default_date;}

(5) In addition to the member functions of the class, there are some common functions associated with the class, we choose to put them into a namespace, so that the use of the class is clearer.

namespace chrono{    class  date{        /* ... */     };     int diff (Date A, date B);     bool leapyear (int  y);    Date Next_weekday (date d);}    

2. What exactly is in the class

(1) The default constructor. The default constructor is a constructor that does not use parameters, and the default constructor generated by the compiler implicitly calls the class member and the default constructor of the base class. Because const and references must be initialized, classes that contain const and references cannot be constructed by default unless the default constructor is explicitly defined.

(2) Copy of the object. The default meaning of T1 = T2 is to copy the members of the T2 to T1 individually. If there is a pointer in the class, then the pointer points to only one copy of the data, but will be deleted two times when the T1,T2 is deleted, which is quite dangerous, so the copy constructor is the initialization of the uninitialized store, and the copy assignment operator must correctly handle a well-structured object.

(3) Class object as a member. The constructor of a member executes before the constructor of the class itself executes, in the order in which the members are declared in the class. When the object is destroyed, its own destructor is executed first, and then the destructor of each member is executed in the inverse order of the member declaration. Constructors are constructed from the bottom up, and destructors are removed from the top-down objects. In addition, for a static constant integer member, you can initialize it with a constant expression in the member declaration.

//Curious.hclasscurious{ Public:Static Const intC1 =7;//OK, but remember to define    Static intC2 = One;//error, not const    Const intC3 = -;//error, not static    Static Const intC4 = f ( -);//error, not a constant expression    Static Const DoubleC5 =7.0;//error, not integral type};//Curious.cppConst intcurious::c1;//...

(4) An array of members. If you have a default constructor when you construct an object of a class, you can define an array of this class without explicitly providing an initial formula.

(5) Non-local object storage. Sometimes, we define a static class member that is used only once:

class zlib_init{    zlib_init ();     // enable zlib to use    // make the zlib do the final cleanup }; class zlib{    static  zlib_init x;     // ...};

In a program consisting of several compilation units, it is not guaranteed that a static member object of "X" must be initialized before it is first used and destroyed after its last use. We can use the first switch technology to solve the sequential dependency problem, but there is no similar last-time switch structure:

 class   zlib{ static  bool   initialized;  static  void  Initialize () {/*   initialize  */ initialized = true  ;}  public  :  //     no constructors  void   F () { if  (initialized = false  ) initialize (); }}

(6) The temporary object. A temporary object is destroyed after the expression at which it was established, but the temporary object becomes a const reference or is used to name the object's initial form and will continue to exist.

(7) For a union, it is best to use it only in the underlying code, or as part of the class implementation, to preserve what information is stored in the union by the class.

  

The road to coding--re-learning C + + (4): Defining a correct class

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.