Tuesday, September 25, 2007

Effecitve C++ (18-20)

Item 18: Make interfaces easy to use correctly and hard to use incorrectly

example of Date(int month, int day, int year); To avoid Date d(1000,2000,3)
Smart pointer.

Item 19: Treat class design as type design

questions of how to design your class.

Item 20: Prefer pass-by-reference-to-const to pass-by-value

pass-by-value: function parameters are initialized with copies of the actual arguments, and function callers get back a copy of the value returned by the function. These copies are produced by the objects' copy constructors. This can make pass-by-value an expensive operation. Example
class Person{ ...};
class Student: public Person{ ...};
bool valid (Student s); // define function
...
Student plato;
pOK = valid(plato); // call the function

The correct and desired:
bool valid(const Student& s); // pass by reference

This is much more efficient: no constructors or destructors are called, because no new objects are being created. Passing parameters by reference also avoids the slicing problem. When a derived class object is passed (by value) as a base class object, the base class copy constructor is called, and the specialized features that make the object behave like a derived class object are "sliced" off. You're left with a simple base class object. Example:
class Window{
virtual void display() const;
};
class subWindow: public Window{
virtual void display() const;
}

void print(Window w){
w.display();
}

subWindow sb; // something wrong here because (look at below)
print(sb);

The parameter w will be constructed— as a Window object, and all the specialized information that made sb act like a subWindow object will be sliced off. Inside print, w will always act like an object of class Window (because it is an object of class Window), regardless of the type of object passed to the function. In particular, the call to display inside print will always call Window::display, never subWindow::display. Correct one:
void print(const Window& w){ // will not be sliced
w.display();
}

if you have an object of a built-in type (e.g., an int), it's often more efficient to pass it by value than by reference.

No comments:

Post a Comment