Constructors and Using Objects in C++

1. Constructors

A constructor is invoked to create an object.

Constructors are a special kind of function, with three peculiarities:

  • Constructors must have the same name as the class itself.
  • Constructors do not have a return type—not even void.
  • Constructors are invoked when an object is created. Constructors play the role of initializing objects.

The constructor has exactly the same name as the defining class. Like regular functions, constructors can be overloaded (i.e., multiple constructors with the same name but different constructor overloading signatures), making it easy to construct objects with different sets of data values.

It is a common mistake to put the void keyword in front of a constructor. For example,

void Circ1e()

{

}

Most C++ compilers will report an error, but some will treat this as a regular function, not as a constructor.

Constructors are for initializing data fields. The data field radius does not have an initial value, so it must be initialized in the constructor (lines 13 and 19 in Listing 9.1). Note that a variable (local or global) can be declared and initialized in one statement, but as a class mem­ber, a data field cannot be initialized when it is declared. For example, it would be wrong to replace line 8 in Listing 9.1 by

double radius = 5; // Wrong for data field declaration

A class normally provides a constructor without arguments (e.g., Circle()). Such con­structor is called a no-arg or no-argument constructor.

A class may be defined without constructors. In this case, a no-arg constructor with an empty body is implicitly defined in the class. Called a default constructor, it is provided auto­matically only if no constructors are explicitly defined in the class.

Data fields may be initialized in the constructor using an initializer list in the following syntax:

ClassName(parameterList)

: datafield1(value1), datafield2(value2) // Initializer list

{

// Additional statements if needed

}

The initializer list initializes datafieldl with valuel and datafield2 with value2.

For example,

Constructor in (b), which does not use an initializer list, is actually more intuitive than the one in (a). However, using an initializer list is necessary to initialize object data fields that don’t have a no-arg constructor. This is an advanced topic covered in Supplement IV.E on the Companion Website.

2. Constructing and Using Objects

An object’s data and functions can be accessed through the dot (.) operator via the object’s name.

A constructor is invoked when an object is created. The syntax to create an object using the no-arg constructor is

ClassName objectName;

For example, the following declaration creates an object named circlel by invoking the Circle class’s no-arg constructor.

Circle circle1;

The syntax to create an object using a constructor with arguments is

ClassName objectName(arguments);

For example, the following declaration creates an object named circle2 by invoking the Circle class’s constructor with a specified radius 5.5.

Circle circ1e2(5.5);

In OOP term, an object’s member refers to its data fields and functions. Newly created objects are allocated in the memory. After an object is created, its data can be accessed and its dot operator functions invoked using the dot operator (.), also known as the object member access operator:                                                                                                                                                    member access operator

  •  objectName.dataField references a data field in the object.
  •  objectName.function(arguments) invokes a function on the object.

For example, circl e1. radi us references the radius in ci rcl e1, and ci rcle1. getArea() invokes the getArea function on ci rcl e1. Functions are invoked as operations on objects.

The data field radius is referred to as an instance member variable or simply instance variable, because it is dependent on a specific instance. For the same reason, the function getArea is referred to as an instance member function or instance function, because you can invoke it only on a specific instance. The object on which an instance function is invoked is called a calling object.

The following points on classes and objects are worth noting:

  • You can use primitive data types to define variables. You can also use class names to declare object names. In this sense, a class is also a data type.
  • In C++, you can use the assignment operator = to copy the contents from one object memberwise copy to the other. By default, each data field of one object is copied to its counterpart in the other object. For example,

circ1e2 = circlel;

copies the radius in circle1 to circle2. After the copy, circle1 and circle2 are still two different objects but have the same radius.

  • Object names are like array names. Once an object name is declared, it represents an object. It cannot be reassigned to represent another object. In this sense, an object name is a constant, though the contents of the object may change. Memberwise copy constant object name can change an object’s contents but not its name.
  • An object contains data and may invoke functions. This may lead you to think that an object is quite large. It isn’t, though. Data are physically stored in an object, but func­tions are not. Since functions are shared by all objects of the same class, the compiler creates just one copy for sharing. You can find out the actual size of an object using the sizeof function. For example, the following code displays the size of objects object size circle1 and circle2. Their size is 8, since the data field radius is double, which takes 8 bytes.

Circle circlel;

Circle circ1e2(5.0);

cout << sizeof(circlel) << endl;

cout << sizeof(circ1e2) << endl;

Usually you create a named object and later access its members through its name. Occa­sionally you may create an object and use it only once. In this case, you don’t have to name it. Such objects are called anonymous objects.

The syntax to create an anonymous object using the no-arg constructor is

ClassName()

The syntax to create an anonymous object using the constructor with arguments is ClassName(arguments)

For example, circlel = Circle();

creates a Circle object using the no-arg constructor and copies its contents to circlel.

circlel = Circ1e(5);

creates a Circle object with radius 5 and copies its contents to circlel.

For example, the following code creates Circle objects and invokes their getArea() function.

cout << “Area is ” << Circ1e().getArea() << endl;

cout << “Area is ” << Circle(5).getArea() << endl;

As you see from these examples, you may create an anonymous object if it will not be referenced later.

Source: Liang Y. Daniel (2013), Introduction to programming with C++, Pearson; 3rd edition.

Leave a Reply

Your email address will not be published. Required fields are marked *