Initialization and Constructors

  1. Overview
    1. When creating a new object, we often would like data members to have a default value
    2. It's tedious to initialize an object's data members one by one
    3. A constructor is a special method that initializes an object's attributes
  2. Class member initialization
    1. C++11 allows data members to be initialized when the data members are declared
    2. Example that initializes Student's name, gender, and gpa
      class Student
      {
      	public:
      		void SetName(string name);
      		string GetName();
      		void Print();
      	
      	private:
      		string name = "John Doe";
      		char gender = 'M';
      		double gpa = 0;
      };
      
      int main() 
      {
      	Student s;
      	s.Print();   // John Doe, M, 0	
      }
      
  3. Default constructors
    1. An alternative to initializing data members in the class definition is to create a constructor, which is a special function that is called when an object is created
    2. The default constructor is a constructor that has no parameters
      class Student
      {
      	public:
      		Student();   // default constructor declaration
      		...
      
      	private:
      		string name;
      		char gender;
      		double gpa;	
      };
      
      // default constructor definition
      Student::Student()
      {
      	name = "John Doe";
      	gender = 'M';
      	gpa = 0.0;
      }
      
    3. When a student is declared, the default constructor is called automatically
      Student s;    // Default constructor is called
      s.Print();    // John Doe, M, 0
      
    4. The default constructor is implicitly defined when there are no other constructors defined
    5. When you provide your own constructor (a constructor that takes parameters), the default constructor is no longer defined, so you must add it back explicitly if you still want to use it
  4. Overloaded constructors
    1. An overloaded constructor is a constructor that has at least one parameter
    2. General format:
      class ClassName
      {
      	public:
      		// Overloaded constructor
      		ClassName(type1 param1, type2 param2, etc.)
      		{
      			// Set member1, member2, etc. to param1, param2, etc.
      		}
      
      	private:
      		type1 member1;
      		type2 member2;	
      }
      
    3. Example overloaded constructor for a Student
      class Student
      {
      	public:
      		Student(string name, char gender, double gpa);	
      		...
      	
      	private:
      		string name;
      		char gender;
      		double gpa;	
      };
      
      // Overloaded constructor
      Student::Student(string name, char gender, double gpa)
      {
      	this->name = name;
      	this->gender = gender;
      	this->gpa = gpa;
      }
      
      1. Constructor always uses the same name as the class
      2. this is an implicit parameter that refers to the object
      3. this-> is used to disambiguate between the member name and the parameter name (this->name is the member name)
  5. Using the constructor
    1. Called when declaring an object
      // Calls the constructor 
      Student s("Bob", 'M', 3.0);   
      
    2. Can also be called directly/explicitly
      // Call constructor explicitly
      s = Student("Sue", 'F', 3.5);
      
  6. Constructors can ensure that initializer data is within given contraints
    // Constructor 
    Student::Student(string name, char gender, double gpa)
    {
    	this->name = name;
    	
    	// Ensure gender is M or F
    	this->gender = toupper(gender);
    	if (gender != 'M' && gender != 'F')
    		this->gender = '?';
    		
    	// Ensure gpa is between 0 and 4
    	if (gpa < 0)
    		this->gpa = 0;
    	else if (gpa > 4)
    		this->gpa = 4;
    	else
    		this->gpa = gpa;
    }
    
  7. Constructors with default parameter values
    1. Constructor parameters may be assigned default values
    2. Default values given in contructor declaration using assignment operator
      class Student
      {
      	public:
      	    // gender and gpa given default values 
      		Student(string name, char gender = '?', double gpa = 0);	
      		...
      	
      	private:
      		string name;
      		char gender;
      		double gpa;	
      };
      
      int main()
      {
      	Student s1("Bob");            // gender is '?', gpa is 0 
      	Student s2("Pam", 'F');       // gpa is 0
      	Student s3("Jim", 'M', 3.4);  // No default values used  
      }
      
    3. A constructor with all default values may serve as the default constructor
      class Student
      {
      	public:
      	    // All parameters have default values 
      		Student(string name = "No Name", char gender = '?', double gpa = 0);	
      		...
      };
      
      int main()
      {
          // name = "No Name", gender = '?', gpa = 0
      	Student stu;   
      }
      
  8. Alternative constructor syntax
    1. Most C++ programers prefer to use an alternate and more terse syntax for initializing attributes
    2. General format:
      ClassName(type1 param1, type2 param2) : attr1(param1), attr2(param2)
      {
      }
      
    3. Example Student constructor
      // Default constructor
      Student() : name("John Doe"), gender('M'), gpa(2.0)
      {
      }
      
      // Overloaded constructor
      Student(string name, char gender, double gpa) :
      	name(name), gender(gender), gpa(gpa)
      {
      }