Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: minor editorial changes

...

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
bgColor#ccccff
langcpp
// 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
bgColor#ccccff
langcpp
// ... 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
bgColor#ccccff
langcpp
#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);
}

...