Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CQG / Задание1 / HDS_VCPP_Programming Rules.doc
327.68 Кб

Const Member Functions

Rec. 28.If the behavior of an object depends on data outside the object, this data should not be modified by const member functions.

Rec. 29.A member function that does not affect the state of an object (its instance variables) should be declaredconst.

The behavior of an object can be affected by data outside the object. Such data must not be modified by a const member function.

At times, it is desirable to modify data in a const object (such as having a cache of data for performance reasons). In order to avoid explicit type conversions from a const type to a non-const type, the only way is to store the information outside the object (see Example 55). This type of data should be seen as external data that does not affect the class.

Member functions declared as constmay not modify member data and are the only functions that can be invoked on a const object. (Such an object is clearly unusable without const methods). Aconstdeclaration is an excellent insurance that objects will not be modified (mutated) when they should not be. SeeExample 25.

A great advantage provided by C++ is the ability to overload functions with respect to their const-ness. (Two member functions may have the same name where one is const and the other is not). See Example 26.

Non-const member functions are sometimes invoked as so-called lvalues (as a location value at which a value may be stored). A const member function may never be invoked as an lvalue.

Constructors and Destructors

Rule 45. Destructors must never throw exceptions.

Rec. 30.Constructors should not throw exceptions. Use an additional initializing method that throws exceptions if it is necessary during initialization.

Rec. 31.All classes used as base classes and having virtual functions should define a virtual destructor.

Rec. 32.A class that usesnewto allocate instances managed by the class should define a copy constructor.

Rec. 33.Avoid using global objects in constructors and destructors.

If a class constructor throws an exception, the destructor will never be called and any allocated memory will not be freed. Therefore, we do not recommend throwing exceptions in constructors and destructors. Move all statements that may throw exceptions into a special initializing member function. See Examples 27and28.

If a class having virtual functions but without virtual destructors is used as a base class, there may be a surprise if pointers to the class are used. If such a pointer is assigned to an instance of a derived class and if deleteis then used on this pointer, only the base class destructor will be invoked. If the program depends on the derived class destructor being invoked, the program will fail. SeeExample 29.

On the other hand, if a class is an interface and, therefore, is used through multiple inheritance and never as a type holder for derived classes, it may have no virtual destructors.

A copy constructor is recommended to avoid surprises when an object is initialized using an object of the same type. If an object manages the allocation and deallocation of an object on the heap (the managing object has a pointer to the object to be created by the class constructor), only the value of the pointer will be copied. This can lead to two invocations of the destructor for the same object (on the heap), probably resulting in a run-time error. See Examples30and31.

Sometimes, it is desired to let objects in a class share a data area. In such a case, it is not necessary to define a copy constructor. Instead, it is necessary to make sure that this data area is not deallocated as long as there are pointers to it.

If no reasonable copy constructor can be provided, declare it as privateto prohibit a class instance from being copy constructed.

The similar problem exists for the assignment operator (=). SeeAssignment Operators.

Concerning the initialization of statically allocated objects, it is not certain that other static objects (for example, global objects) will be initialized (see Example 32). This is because the order of initialization of static objects defined in various compilation units is not defined in the language standard. There are ways of avoiding this problem, all of which require some extra work. SeeExample 33.

You must know what you are doing if you invoke virtual functions from a constructor in the class. If virtual functions in a derived class are overridden, the original definition in the base class will still be invoked by the base class constructor. Override, then, does not always work when invoking virtual functions in constructors. See Example 34.