...
Code Block | ||||
---|---|---|---|---|
| ||||
class Employee {
public:
Employee(string theName) : name(theName) {};
string getName() const {return name;}
virtual void print() const {
cout << "Employee: " << getName() << endl;
}
private:
string name;
};
class Manager : public Employee {
public:
Manager(string theName, Employee theEmployee) :
Employee(theName), assistant(theEmployee) {};
Employee getAssistant() const {return assistant;}
virtual void print() const {
cout << "Manager: " << getName() << endl;
cout << "Assistant: " << assistant.getName() << endl;
}
private:
Employee assistant;
};
int main () {
Employee coder("Joe Smith");
Employee typist("Bill Jones");
Manager designer("Jane Doe", typist);
coder = designer; // slices Jane Doe!
coder.print();
}
|
In this code, class Manager
is derived from class Employee
and adds additional information, namely the data member assistant
. In main
, the object designer
of class Manager
, which contains an assistant
data member typist
, is copied by value to the object coder
of class Employee
. This results in the designer
object being sliced, and only the Employee
information is copied. Hence, the print()
statement results in the output:
Code Block |
---|
Employee: Jane Doe
|
The information about Jane Doe's assistant is lost.
...
Code Block | ||||
---|---|---|---|---|
| ||||
int main () {
Employee *coder = new Employee("Joe Smith");
Employee *typist = new Employee("Bill Jones");
Manager *designer = new Manager("Jane Doe", *typist);
coder = designer;
coder->print();
}
|
Now, the object designer
is not sliced, and the output is:
Code Block |
---|
Manager: Jane Doe
Assistant: Bill Jones
|
...
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
}
|
...
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();
}
|
...
Code Block | ||||
---|---|---|---|---|
| ||||
class Employee {
public:
Employee(string theName) : name(theName) {};
virtual ~Employee();
string getName() const {return name;}
virtual void print() const = 0;
private:
string name;
};
|
...
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
OOP33-CPP | low | probable | high | P2 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
| 3072,3073 |
Bibliography
[Dewhurst 02] Gotcha #38, "Slicing"
[ISO/IEC 14882-2003] Section 9, "Classes"
[Sutter 00] GotW #22: "Object Lifetimes - Part I"
...