...
Using the same class definitions as the noncompliant code example, this compliant solution modifies the definition of f() to require raw pointers to the object, removing the slicing problem:.
| Code Block | ||||
|---|---|---|---|---|
| ||||
// Remainder of code unchanged...
void f(const Employee *e) {
if (e) {
std::cout << *e;
}
}
int main() {
Employee coder("Joe Smith");
Employee typist("Bill Jones");
Manager designer("Jane Doe", typist);
f(&coder);
f(&typist);
f(&designer);
}
|
This compliant solution also complies with EXP34-C. Do not dereference null pointers in the implementation of f(). With this definition, the the program correctly outputs :the following.
| Code Block |
|---|
Employee: Joe Smith Employee: Bill Jones Manager: Jane Doe Assistant: Employee: Bill Jones |
...
An improved compliant solution, which does not require guarding against null pointers within f(), uses references instead of pointers:.
| Code Block | ||||
|---|---|---|---|---|
| ||||
// ... Remainder of code unchanged ...
void f(const Employee &e) {
std::cout << e;
}
int main() {
Employee coder("Joe Smith");
Employee typist("Bill Jones");
Manager designer("Jane Doe", typist);
f(coder);
f(typist);
f(designer);
} |
...
This compliant solution uses a vector of std::unique_ptr objects, which eliminates the slicing problem:.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <iostream>
#include <memory>
#include <string>
#include <vector>
void f(const std::vector<std::unique_ptr<Employee>> &v) {
for (const auto &e : v) {
std::cout << *e;
}
}
int main() {
std::vector<std::unique_ptr<Employee>> v;
v.emplace_back(new Employee("Joe Smith"));
v.emplace_back(new Employee("Bill Jones"));
v.emplace_back(new Manager("Jane Doe", *v.front()));
f(v);
} |
...