Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
bgColor#ccccff
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->print();
}

Now, the object designer is not sliced, and the output is:

Manager: Jane Doe
Assistant: Bill Jones

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
bgColor#ccccff

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
}

Alternatively, references may be used to refer to the various derived employee objects.

Code Block
bgColor#ccccff

int main () {
  Employee coder("Joe Smith");
  Employee typist("Bill Jones");
  Manager designer("Jane Doe", typist);

  Employee &toPrint = designer;  // Jane remains entire
  toPrint.print();
}

The most effective way to avoid slicing of objects is to ensure, whenever possible, that polymorphic base classes are abstract.

Code Block
bgColor#FFCCCC

class Employee {
public:
  Employee(string theName) : name(theName) {};
  virtual ~Employee();
  string getName() const {return name;}
  virtual void print() const = 0;
private:
  string name;
};

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.

...