Copying a polymorphic object by value can easily result in the object being sliced. That is, only part of the information associated with the object is copied, and the remaining information is lost.
Non-Compliant Code Example
This code example is non-compliant because of the unintended data loss.
...
The information about Jane Doe's assistant is lost.
Compliant Solution (Pointers)
Assuming exactly the same class structure as above, if pointers to the objects are used so that objects are copied by reference, then slicing does not occur.
...
Code Block |
---|
Manager: Jane Doe Assistant: Bill Jones |
Compliant Solution (Smart Pointers)
Alternatively, it is often safer to use a smart pointer, like std::auto_ptr, to hold the address of allocated memory. This is typically more robust than the use of raw pointers.
Code Block | ||
---|---|---|
| ||
int main () { auto_ptr<Employee> coder( new Employee("Joe Smith") ); auto_ptr<Employee> typist( new Employee("Bill Jones") ); auto_ptr<Manager> designer( new Manager("Jane Doe", *typist) ); coder = designer; // Smith deleted, Doe xferred coder->print(); // everyone deleted } |
Compliant Solution (References)
Alternatively, references may be used to refer to the various derived employee objects.
Code Block | ||
---|---|---|
| ||
int main () { Employee coder("Joe Smith"); Employee typist("Bill Jones"); Manager designer("Jane Doe", typist); Employee &toPrint = designer; // Jane remains entire toPrint.print(); } |
Compliant Solution (Abstract Base Class)
The most effective way to avoid slicing of objects is to ensure, whenever possible, that polymorphic base classes are abstract.
...
The presence of a pure virtual function in the Employee base class ensures that no objects of type Employee will exist, and slicing cannot occur.
Risk Assessment
Slicing results in information being lost, which could lead to a program not working properly and hence to a denial-of-service attack.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
OBJ33-CPP | 1 (low) | 2 (probable) | 1 (high) | P2 | L3 |
References
Wiki Markup |
---|
\[[Dewhurst 02|AA. References#Dewhurst 02]\] Gotcha #38, "Slicing" \[[ISO/IEC 14882-2003|AA. References#ISO/IEC 14882-2003]\] Section 9, "Classes" \[[Sutter 00|AA. References#Sutter 00]\] GotW #22: "Object Lifetimes - Part I" |
...