Sei sulla pagina 1di 7

Constructors

Default arguments
- Any C++ function can provide default values for its input function arguments
- If a value is not specified in a function call, the default value is assigned and sent to the
called function
- Consider the following example with a standard (non-class member) function

#include <iostream>
using namespace std;

int add( int a=10, int b=2 );

main()
{
int f1 = add();
cout << f1 << endl;
}

int add( int a, int b )


{
return (a+b);
}

Output
12

- When the compiler processes the add function it does not “see” any values provided for the
two arguments
- As a result, it assigns the default values, 10 and 2, to a and b when calling the function
- Users, however, can override the default values by providing their own values in the function
call
- As a result, the same function can look very different when it is called

main()
{
int f1 = add();
int f2 = add( 14, 7);
cout << f1 << “ “ << f2 << endl;
}

Output
12 21

- Default values are optional and not required for every function argument
- For multiple arguments, however, a rule must be enforced for default values or the compiler
might get confused
- Consider the following scenario

#include <iostream>
using namespace std;

int add( int a=10, int b );

main()
{
int f1 = add( 20 );
cout << f1 << endl;
}
int add( int a, int b )
{
return (a+b);
}

- When the compiler encounters the function call, which argument (a or b) should it assign the
value 20?
- Should it override the value 10 and assign it to a or should it be assigned to b?
- Obviously, this is indeterminate and cannot be resolved by the compiler
- In fact, this code example will not compile and report the following errors

error: default argument missing for parameter


2 of `int add(int, int)'
In function `int main()':
error: too few arguments to function `int
add(int, int)'
error: at this point in file
In function `int add(int, int)':
error: default argument missing for parameter
2 of `int add(int, int)'

- To clear up the confusion, a rule is enforced when using default values and multiple
arguments
- All arguments to the right of an argument with a default value must be specified
- In other words, their can be no "holes" in your default parameter list
- This rule helps the compiler determine which arguments to assign values to in a function call
- Correcting our example according to this rule, we now have the following

#include <iostream>
using namespace std;

int add( int a, int b=2 );

main()
{
int f1 = add( 20 );
cout << f1 << endl;
}

int add( int a, int b )


{
return (a+b);
}

Output
22

- With this rule, values specified will be assigned to arguments beginning from the left
- In this example, the value 20 is assigned to a and the default value 2 is assigned to b
- Consider another example with an added function argument
- In this example, we have provided a default value for b but not for c

#include <iostream>
using namespace std;

int add( int a, int b=2, int c );

main()
{
int f1 = add( 20 );
cout << f1 << endl;
}

int add( int a, int b, int c )


{
return (a+b+c);
}

- Since we have not specified a value for c according to the rule, the compiler reports the
following error

error: default argument missing for parameter 3 of 'int


add(int, int, int)'

- The rule states we must provide a default value for all arguments to the right of the first one
with a default value
- The first argument with a default value is b, so we must provide a default value for
argument c
- Correcting our program, we have the following

#include <iostream>
using namespace std;

int add( int a, int b=2, int c=4 );

main()
{
int f1 = add( 20 );
cout << f1 << endl;
}

int add( int a, int b, int c )


{
return (a+b+c);
}

Output
26

Constructors
- Special type of class member function
- Automatically called upon object instantiation
- Same name as the class
- No return type
- Arguments allowed, can have default arguments
- Consider the following class definition for a three-dimensional point in space
- A constructor is defined inline (definition included with declaration) with default argument
values

#include <iostream>
using namespace std;

class Point
{
private:
float x, y, z;

public:
Point(float c1=0.0, float c2=0.0, float
c3=0.0)
{
x = c1;
y = c2;
z = c3;
}
void Print()
{
cout << "x y z: “ << x << “ “ << y <<
“ “ << z << endl;
}
};

- Constructors provide an ideal place to perform any initial housekeeping tasks associated
with objects
- Such tasks could include allocating memory, opening files, or initializing state variables (as
in the example above)
- Recall that constructors are automatically called when objects are instantiated
- As a result, such initial housekeeping tasks will be performed when each object is declared
- This provides an ideal mechanism for assuring that objects will be created correctly when
called in programs
- Object declarations (or instantiations) can look different when using default argument values
- In the example below, two Point objects are instantiated with different x,y,z values

main()
{
Point p;
p.Print();

Point p1( 0.0, 2.0, 3.0 );


p1.Print();
}

Output
x y z: 0.00 0.00 0.00
x y z: 0.00 2.00 3.00

- State variables cannot be initialized in declarations in the class definition as follows

#include <iostream>
using namespace std;

class Point
{
private:
float x = 0.0;
float y = 0.0;
float z = 0.0;

public:
Point(float c1=0.0, float c2=0.0, float c3=0.0)
{
x = c1;
y = c2;
z = c3;
}
void Print()
{
cout << "x y z: “ << x << “ “ << y << “ “ << z <<
endl;
}
};

- This code is will not compile and reports the following errors

error: ISO C++ forbids initialization of member `x'


error: making `x' static
error: ISO C++ forbids in-class initialization of non-
const static
member `x'
error: ISO C++ forbids initialization of member `y'
error: making `y' static
error: ISO C++ forbids in-class initialization of non-
const static
member `y'
error: ISO C++ forbids initialization of member `z'
error: making `z' static
error: ISO C++ forbids in-class initialization of non-
const static
member `z'

- Instead, Initialization should be done in the constructor (or in functions called by the
constructor)

Object Declarations
- Constructors can be called (through object instantiation) in several different ways
- Consider the example below using our Point class

main()
{
Point p1;
Point p2( 1.0, 2.0, 3.0 );
Point p3 = Point( 4.0, 5.0, 6.0);
Point *p4 = new Point();
Point *p5 = new Point( 7.0, 8.0,
9.0 );

p1.Print();
p2.Print();
p3.Print();
p4->Print();
p5->Print();
}

Output
x y z: 0.00 0.00 0.00
x y z: 1.00 2.00 3.00
x y z: 4.00 5.00 6.00
x y z: 0.00 0.00 0.00
x y z: 7.00 8.00 9.00

- Note the various methods of instantiation


- The constructor for objects p1 and p2 are implicitly called with a "shorthand" form
- The constructor for object p3 is explicitly called with a "longhand" form which returns
references to the object
- Note this is implied (no return type in declaration)
- Objects p4 and p5 are dynamically allocated using the new operator differing in default
argument values

Constructor Overloading
- Multiple versions of constructor functions can be written each with the same name but
different arguments
- The constructor functions differ only in their input parameter lists (types and number of
arguments)
- This concept is referred to as function overloading and plays a key role in object-oriented
methodologies
- As we’ll see in detail later, function overloading can be applied to any type of function in C++
- Consider the following example with an extended version of the Point class

#include <iostream>
using namespace std;

class Point
{
private:
float x,y,z;

public:
Point(float c1=0.0, float c2=0.0, float
c3=0.0)
{
x = c1;
y = c2;
z = c3;
}
Point(float *c)
{
x = c[0];
y = c[1];
z = c[2];
}
void Print()
{
cout << "x y z: “ << x << “ “ << y <<
“ “ << z << endl;
}
};

- In this example, we have two constructor functions differing by their input parameter list
- This first constructor accepts three floating point variables in its parameter list

Point(float c1=0.0, float c2=0.0, float


c3=0.0)
{
x = c1;
y = c2;
z = c3;
}

- While the second constructor accepts a pointer to an array of floating point variables

Point(float *c)
{
x = c[0];
y = c[1];
z = c[2];
}

- Objects can be constructed in different ways depending on the type of argument list used in
a program
- Below the first constructor is called for objects p1 and p2 and the second constructor is
called for p3
- In this way, constructor overloading provides class users more flexible ways of declaring
objects

main()
{
float a = 1.0;
float b = 2.0;
float c = 3.0;
float d[3] = { 4.0, 5.0, 6.0 };

Point p1;
Point p2( a, b, c );
Point p3( d );

p1.Print();
p2.Print();
p3.Print();
}

Output
x y z: 0.00 0.00 0.00
x y z: 1.00 2.00 3.00
x y z: 4.00 5.00 6.00

Potrebbero piacerti anche