Peculiar practice spreading . . .

Console dialogs and string scanning don't belong in constructors

©Conrad Weisert, August 1, 2012


Misplaced input

What's wrong with the constructor in this C++ class?

  class Point2  //  Point in a plane
  {float x, y;  //  Coordinates
   
   public:
     Point2()
      {cout << "Please enter the x coordinate for the point:";
       cin  >>  x;
       cout << "Please enter the y coordinate for the point:";
       cin  >>  y;
      }
    .
    .
  };
     .
     .
   Point2  obj;      

 

Readers experienced in C++ or a similar object-oriented language are shocked to see console dialog inside a constructor. A console dialog—indeed any input-output—is unrelated to the purpose of a constructor function. Yet, we see similar examples in recent textbooks, articles, and presentations!

A year ago, we noted the inappropriate use of console dialogs in procedural code. Embedding them in object-oriented constructors is many times worse, because:

Presumably, the users of the Point2 class know what parameters its constructors expect. Therefore, the user code can obtain or generate those parameters in any way it chooses before invoking the appropriate constructor. The following code respects the object paradigm:

  class Point2  //  Point in a plane
  {float x, y;  //  Coordinates
   
   public:
     Point2(const float _x=0, const float _y=0)
         : x(_x), y(_y)    {}
    .
    .
  };
    .
    .

   {float c1, c2;
    cout << "x coordinate?  ";  cin  >>  c1;  // or other code to obtain
    cout << "y coordinate?  ";  cin  >>  c2;  //   or compute the values
    Point2 obj(c1, c2);
   }


 

Who handles errors?

Two kinds of errors may occur in the input. The user may enter:

  1. characters that do not form a legal floating-point number, or

  2. a value outside the range allowed for a Point2 object.

In the original version detecting, diagnosing, and recovering from both kinds of error must be the responsibility of the Point2 class, specifically the constructor. But an illegal character in numeric input has nothing whatever to do with points in a plane. In the corrected version the input or other user code is responsible for type 1 errors, and the constructor is responsible only for type 2. If all floating point values are legitimate, the constructor needs no error checking or recovery code at all.

A non-dialog variant

Some examples don't actually conduct a dialog with a human user, but still embed input or string-parsing operations inside a constructor for no purpose. Here's a java example from a 2011 textbook:

  class Student {
   String name;
   double gpa;
      .
      .
  public Student (String s)        //  Constructor
  { Scanner sc = new Scanner (s);
    name = sc.next();
    gpa  = sc.nextDouble();
  }  
    .
    .
 }

a strange and error-prone choice, since one could easily just define a two-parameter constructor. (Scanner is a Java standard library class for parsing character strings.)

Doesn't everyone already understand all that?

Sure, we can safely assume that any programmer who grasps the object paradigm would avoid the original version at the top of this article and be appalled by it. We're posting this article for the benefit of beginners and students who may see such an example in a textbook or on the Internet and then think it's okay or even desirable to emulate it.


Last modified 31 July 2001

Return to technical articles .
Return to IDI home page.