Effective C + + 38-42

Source: Internet
Author: User

38. Never redefine inherited default parameter values.

Redefining a function's default parameter value means redefining the function, not the virtual function, so you will consider the reason why you cannot redefine the default parameter values for virtual functions: Virtual functions are dynamically bound and default parameter values are statically bound.

A static type is a type declared in a program, whereas a dynamic type refers to the type of the actual object, for example, a chestnut:

Class a{public:virtual void Fun (int a=0) const{cout<<a<<endl;}}; Class b:public a{public:virtual void fun (int A =2) const{cout<<a<<endl;}}; int main () {b* PB = new B ();//pb static type is b*a* PA = pb;//pa static type is a*,//but a static type of a pointer is not necessarily a dynamic type, such as PA its dynamic type is a type B object, which is implemented by dynamic binding pb-& Gt;fun ();p a->fun ();
Virtual functions are dynamically bound, but the default parameter values are statically bound, that is, for PB,PA called virtual functions, which use the default parameter values are statically bound, PA binding is a class of a= 0, and PB is bound by the Class B a=2, the two are different, although the function is called B dynamic binding virtual function, However, the default parameters are different and the output is different.


39. Avoid the "downward transition" inheritance hierarchy.

A pointer to a derived class from a base class pointer is called a down conversion, typically using static_cast to cast a base-class pointer to a derived class pointer. Downward conversions are unsightly, prone to errors, and difficult to understand, upgrade and maintain.

Elimination of Down conversion: use virtual function calls instead. The first method is very simple to understand, but for some classes that do not apply, such as the base class scope is too large to cause 7 of some derived classes should not have the functionality of this function, so each virtual function of these classes is called an empty operation, or as a pure virtual function, and the default implementation returns the wrong operation. The second method is to enforce the type constraint so that the pointer's declaration type is the same as the true pointer type you know. That is, with these downward conversions, some settings are used to filter out pointers that do not have a true pointer type, leaving only the pointers that need to be manipulated and calling their functions with their actual types.

If you encounter situations that must be converted, do not use static_cast, but instead use a secure, dynamic_cast for polymorphism, and when you use dynamic_cast for a pointer, try the conversion first, or return a null pointer if a valid pointer is returned successfully.


40. By layering to reflect the "one" or "use." To achieve ".

Makes an object of a Class A data member of another class, which allows one class to be constructed on top of another class, called a layered layering, also known as a composition, inclusion, or embedding.

For a concept that is easy to understand, for a person, there are attributes such as name,address,phone, but it cannot be said that the person is a Name.

For the "use.. To implement ", is actually called other classes of objects as the main data members of the class, using the function of this class interface to implement the new class functions and interfaces.


41. Differentiate between templates and inheritance.

Depending on the purpose of the dependent class, such as if the dependent class is the behavior of the class, it is inherited, if the dependent class is the object type that the class is manipulating, it is a template. For example, penguins depend on birds, the interface in birds determines the behavior in the Penguin class, that is, the two are inheritance relationships, and when implementing a set, the collection class depends on the class T, because the class T is the object of operation of the collection class, this is the template. The implementation of a template assumes that a class can invoke a function such as the constructor of T, which is characterized by the behavior of the class template that is not dependent on t anywhere, and that the behavior does not depend on the type.

When the type of an object does not affect the behavior of a function in a class, a template is used to generate such a set of classes.

When the type of an object affects the behavior of a function in a class, inheritance is used to obtain such a set of classes.


42. Use private inheritance wisely.

Private inheritance is not a "is a" relationship. If the inheritance relationship between two classes is private, the compiler generally does not convert the derived class object to a base class object. When a private inheritance occurs, the members of the base class's public and protected types become private members of the derived class. Private inheritance means "with ... Implementation ", private inheritance is purely an implementation technology. Private inheritance is only an inheritance implementation, and the interface is ignored. Private inheritance is meaningless in the software "design" process, but only when the software is "implemented".

For layering, also useful ... The meaning of implementation, for hierarchical and private inheritance, use hierarchies whenever possible, and use private inheritance if necessary. It is recommended to use private inheritance when used to protect members and have virtual functions involved.

For a base class, used only as an implementation of other classes, using hierarchies as private members of other classes, but not abstract classes, causing them to be arbitrarily called by others resulting in an error. This is required to use private inheritance, for which a base class with implementation but only for a particular purpose, changes its interface to the protected type, and the class that correctly uses it uses the base class safely using private inheritance without layering.

For templates, which is one of the most useful components of C + +, however, instantiating a template can instantiate code that implements this template, such as the code that makes up set<int> and set<double> is a completely separate two-part code that can cause code bloat. Improved method: Create a generic class that stores void* pointers to objects. Create another set of classes to ensure type safety using the generic class. To implement stack stack as an example, first build a generic class for the stack:

Class GENERICSTACK{PROTECTED://Implementation classes use private inheritance to inherit this generic class, so the interface is protected genericstack (); ~genericstack (); void push (void* object); /Use pointer void* pop (); bool Empty () const;private:struct stacknode{void *data; Stacknode *next;//use pointers in the stack to pass data and save data, the node does not release the memory that the void pointer points to when it is refactored. Stacknode (void *newdata,stacknode *nextnode):d ata (NewData), Next (NextNode) {}}; Stacknode *top; Genericstack (const genericstack&);//Prevent copying and assignment genericstack& operator= (const genericstack&);};
and to implement the concrete class of the stack through the private inheritance of this class to achieve the function, and can use the template to complete the work perfectly:

Template <class t>class stack:private genericstack{public:void push (t* objectptr) {genericstack::p ush (objectPtr );} t* pop () {return static_cast<t*> (genericstack::p op ());} BOOL Empty () const {return genericstack::empty ();}};
With the use of private inheritance, the general class GENERICSTATCK is implemented as its implementation, and its interface functions are inline functions, with little consumption, and using templates to implement type-safe judgments. For creating any type of stack, you can simply recompile this three simple inline function instead of the complex implementation in the generic class, which greatly reduces the cost of the program.

This code is amazing and almost perfect. The template is used first, and the compiler automatically generates all the interfaces according to your needs. Because templates are used, these classes are type-safe and type errors can be found during compilation. Because the member function of Genericstack is a protection type, it is not possible for a user to bypass an interface class to invoke it. Because the interface member functions of this template are implicitly declared inline, the use of these classes does not result in a running overhead, and the code is generated as if the user were to write directly using Genericstack. Because Genericstack is using the void* pointer, the code for the Operation stack requires only one copy, while the different types simply compile the simple inline function in the template template. In short, this design allows the code to achieve the highest efficiency and the highest type safety.

Effective C + + 38-42

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.