Describing the Problem
Suppose you're designing a class whose objects must neither be copied nor assigned to. Because the compiler declares a copy constructor and an assignment operator implicitly, clients will still be able to copy and assign such objects:
explicit Myfile(const char * name);
virtual int open(const char * name);
virtual int close();
Myfile otherfile(datafile);//undesirable copy ctor
third=otherfile; //undesirable assignment
The implicitly declared copy constructor and assignment operator allow the program to copy construct and assign Myfileobjects, possibly causing undefined behavior. The problem is that you have no way to instruct the compiler to not declare these member functions implicitly.
Undesirable implicit conversions present a similar challenge for programmers. Take for example the standard class template std::complex. Its non-default constructor takes one or two floating point arguments:
std::complex <double> compnum2(NULL);//also compiles!
This is well and good. However, because C++ is lenient with respect to conversions of arithmetic types, you can easily get into trouble when the wrong type of argument is passed to the constructor:
std::complex <double> compnum=true;//compiles!
std::complex <double> compnum2=(NULL);//also compiles!
Not only does this weird code compile successfully, you won't even get a warning from your compiler. The problem is that the compiler implicitly converts arguments such as true and NULL to double implicitly. That doubleis then used as the initializer of a complex object. Such conversions most likely indicate a bug but they compile silently. The solution for both problems is based on the same technique. Let's take a look at it.