Professional C__ - Marc Gregoire [499]
Syntax errors: These are rare — interviewers know you can find compile-time bugs with a compiler.
Memory problems: These include problems such as leaks and double deletion.
“You wouldn’t do that” problems: This category includes things that are technically correct but are not recommended. For example, don’t use C-style character arrays, use std::string instead.
Style errors: Even if the interviewer doesn’t count it as a bug, point out poor comments or variable names.
Here’s a find-the-bug problem that demonstrates each of these areas:
class Buggy
{
Buggy(int param);
~Buggy();
double fjord(double inVal);
int fjord(double inVal);
protected:
void turtle(int i = 7, int j);
int param;
double* mGraphicDimension;
};
Buggy::Buggy(int param)
{
param = param;
mGraphicDimension = new double;
}
Buggy::~Buggy()
{
}
double Buggy::fjord(double inVal)
{
return inVal * param;
}
int Buggy::fjord(double inVal)
{
return (int)fjord(inVal);
}
void Buggy::turtle(int i, int j)
{
cout << "i is " << i << ", j is " << j << endl;
}
Take a careful look at the code, and then consult the following corrected version for the answers:
#include class Buggy { public: // These should most likely be public. Buggy(int inParam); // Parameter naming. virtual ~Buggy(); // Recommended to make destructors virtual. Buggy(const Buggy& src); // Provide copy ctor and operator= Buggy& operator=(const Buggy& rhs); // when the class has dynamically // allocated memory. Buggy(Buggy&& src); // C++11: provide move ctor and operator= Buggy& operator=(Buggy&& rhs); // when the class has dynamically // allocated memory to increase // performance. (See Chapter 9). double fjord(double inVal); // int version won't compile. Overloaded // methods cannot differ only in return type. protected: void turtle(int i, int j); // Only last arguments can have defaults. int mParam; // Data member naming double* mGraphicDimension; }; Buggy::Buggy(int inParam) : mParam(inParam) { mGraphicDimension = new double; } Buggy::~Buggy() { delete mGraphicDimension; // Avoid memory leak. mGraphicDimension = nullptr; } Buggy::Buggy(const Buggy& src) { mParam = src.mParam; mGraphicDimension = new double; *mGraphicDimension = *(src.mGraphicDimension); } Buggy& Buggy::operator=(const Buggy& rhs) { if (this == &rhs) { return *this; } mParam = rhs.mParam; delete mGraphicDimension; mGraphicDimension = new double; *mGraphicDimension = *(rhs.mGraphicDimension); return *this; } Buggy::Buggy(Buggy&& src) { mParam = src.mParam; mGraphicDimension = src.mGraphicDimension; src.mGraphicDimension = nullptr; } Buggy& Buggy::operator=(Buggy&& rhs) { if (this == &rhs) { return *this; } mParam = rhs.mParam; mGraphicDimension = rhs.mGraphicDimension; rhs.mGraphicDimension = nullptr; return *this; } double Buggy::fjord(double inVal) { return inVal * mParam; // Changed data member name } void Buggy::turtle(int i, int j) { std::cout << "i is " << i << ", j is " << j << std::endl; // Namespaces } For this example, you should also mention that it’s recommended to use a smart pointer, such as the C++11 shared_ptr, instead of the dumb mGraphicDimension pointer, and include an explanation of why a smart pointer is recommended. CHAPTER 8: DISCOVERING INHERITANCE TECHNIQUES Questions about inheritance usually come in the same forms as questions about classes. The interviewer might also ask you to implement a class hierarchy to show that you have worked with C++ enough to subclass without looking it up in a book. Things to Remember The syntax for subclassing a class The difference between private and protected from a subclass