CQM-HalfHeartedOperation¶
Related routine clusters should be implemented completely or consistently
Required inputs: IR
Motivation
Certain routines of classes must be kept consistent with each other with regard to their implementation, since clients of the class rely on this consistency. If the behavior of individual methods is changed by new implementations or the use of different bindings (virtual vs. non-virtual), this consistency can be destroyed, i.e., the functionality underlying the routine group can become incorrect as a result.
While consistency of application code implementation cannot be expressed in general terms, there are, however, the following specific rules on the part of programming languages that should be observed:
- Java
- Keeping
Object.equals()andObject.hashCode()consistent, because collection classes first identify equivalence candidates usinghashCode. - C++
operator++(void)andoperator++(int)(oroperator--) together to ensure consistency between post and prefix operators.- Implement Copy constructor and
operator=together. - If a class has a virtual method, then the class must also have a virtual destructor.
This means in each case that the change of one of these methods must imply the change of the others.
This rule is based on the CQM Quality Indicator: halbherzige Operationen (p. 207-210).
Reference
Simon, Frank/ Seng, Olaf/ Mohaupt, Thomas (2006): Code-Quality-Management: Technische Qualität industrieller Softwaresysteme transparent und vergleichbar gemacht, 1st ed., Heidelberg, Germany: dpunkt.verlag GmbH.
Possible Messages
Key |
Text |
Severity |
Disabled |
|---|---|---|---|
implement_in_terms |
Implement in terms of other operator |
None |
False |
missing_constructor_and_asgn |
Class with destructor should also declare a copy or move constructor and assignment operator. |
None |
False |
missing_copy_asgn |
Class with copy constructor is missing copy assignment operator. |
None |
False |
missing_copy_constructor |
Class with copy assignment operator is missing copy constructor. |
None |
False |
missing_destructor |
Class with copy or move constructors or assignment operators should also declare a destructor. |
None |
False |
missing_move_asgn |
Class with move constructor is missing move assignment operator. |
None |
False |
missing_move_constructor |
Class with move assignment operator is missing move constructor. |
None |
False |
missing_virtual_destructor |
Class needs a virtual destructor. |
None |
False |
Options¶
This rule shares the following common options: exclude_in_macros, exclude_messages_in_system_headers, excludes, extend_exclude_to_macro_invocations, includes, justification_checker, languages, post_processing, provider, report_at, severity
The following places define options that affect this rule: Stylechecks, Analysis-GlobalOptions
accept_none_destructor¶
accept_none_destructor : bool = False
allow_defaulted_destructor_only¶
allow_defaulted_destructor_only : bool = True
allow_destructor_only¶
allow_destructor_only : bool = False
allow_empty_destructor¶
allow_empty_destructor : bool = True
allow_missing_destructor¶
allow_missing_destructor : bool = False
allow_protected_destructor_only¶
allow_protected_destructor_only : bool = False
ignore_classes_ending_with_string¶
ignore_classes_ending_with_string : set[str] = set()
ignore_classes_inheriting_from¶
ignore_classes_inheriting_from : set[bauhaus.analysis.config.QualifiedName] = set()
ignore_classes_with_member_type¶
ignore_classes_with_member_type : set[bauhaus.analysis.config.QualifiedName] = set()
ignore_macro_expanded_classes¶
ignore_macro_expanded_classes : set[bauhaus.analysis.config.MacroName] = set()
ignore_pod_classes¶
ignore_pod_classes : bool = True