|
|
C++ Programming Tutorial III
Arrays, Pointers,
References |
Arrays of Objects
#include <iostream.h>
class c1 {
int i;
public:
cl(int j) {i=j;} // constructor
int get_i() {return i;}
};
main()
{
cl ob[3] = {1, 2, 3}; // initializers
int i;
for (i=0; i<3; i++) {
cout << ob[i].get_i() << "\n";
return 0;
}
- The syntax for declaring and using an object array is exactly the same as
it is for any other type of variable.
- If a parameterized constructor is used, you can initialize each object in
an array by specifying an initialization list.
- Exercise: Check the syntax to initialize an object array if the
constructor requires multiple parameters.
Pointers to Objects
#include <iostream.h>
class cl {
int i;
public:
cl(int j) {i=j;}
int get_i() {return i;}
};
main()
{
cl ob(88), *p;
p = &ob; // get address of ob
cout << p->get_i(); // use -> to call get_i()
return 0;
}
- When accessing members of a class given a pointer to an object, use the
arrow (->) operator.
Pointers to Object Members
#include <iostream.h>
class cl {
public:
int i;
cl (int j) {i=j;}
};
main()
{
cl ob(1);
int *p;
p = &ob.i; // get address of ob.i
cout << *p; // access ob.i via p
return 0;
}
- You can assign the address of a public member of an object to a pointer.
- Then access that member by using the pointer.
The this Pointer
#include <iostream.h>
class pwr {
double b;
int e;
double val;
public:
pwr (double base, int exp);
double get_pwr() {return val;}
};
pwr::pwr (double base, int exp)
{
b = base;
e = exp;
val = 1;
if (exp==0) return;
for ( ; exp>0; exp--)
val = val * b;
}
main()
{
pwr x(4.0, 2), y(2.5, 1), z(5.7,0);
cout << x.get_pwr() << " ";
cout << y.get_pwr() << " ";
cout << z.get_pwr() << "\n";
return 0;
}
|
|
Alternative:
pwr::pwr(double base, int exp)
{
this->b = base;
this->e = exp;
this->val = 1;
if (exp==0) return;
for ( ; exp>0; exp--)
this->val = this->val * this->b;
}
|
- When a member function is called, it is automatically passed an implicit
argument that is a pointer to the corresponding object instance.
- "this" pointer is very important when operators are overloaded;
and
- Whenever a member function must utilize a pointer to the object that
invoked it.
References
C's Approach:
#include <iostream.h>
void neg (int *i);
main()
{
int x;
x = 10;
cout << x << " negated is ";
neg(&x);
cout << x << "\n";
return 0;
}
void neg (int *i)
{
*i = -*i;
}
|
|
C++'s Approach:
#include <iostream.h>
void neg(int &i); // i now a reference
main()
{
int x;
x = 10;
cout << x << " negated is ";
neg(x); // no longer need the & operator
cout << x << "\n";
return 0;
}
void neg(int &i)
{
i = -i; // i is now a reference, don't need *
}
|
- In C, to create a call-by-reference, you must explicitly pass the address
of an argument to the function.
- In C++, call-by-reference can be done automatically by using reference
parameters.
- To create a reference parameter, precede the parameter's name with an
&.
- The reference parameter automatically refers to (implicitly points to) the
argument used to call the function.
Passing References to Objects
#include <iostream.h>
class cl {
int id;
public:
int i;
cl(int i);
~cl();
void neg(cl &o) {o.i = -o.i;} // no temporary created
};
cl::cl(int num)
{
cout << "Constructing " << num << "\n";
id = num;
}
cl::~cl()
{
cout << "Destructing " << id << "\n";
}
main()
{
cl o(1);
o.i = 10;
o.neg(o);
cout << o.i << "\n";
return 0;
}
Output:
Constructing 1
-10
Destructing 1
- Recall:
- When an object is passed as an argument to a function, a copy of that
object is made.
- Constructor is not called.
- When the function terminates, the destructor is called for the copy.
- When you pass an object by reference, no copy of the object is made.
- Thus, no object is destroyed and no destructor is called when the function
terminates.
Returning References
#include <iostream.h>
char &replace(int i); // return a reference
char s[80] = "Hello There";
main()
{
replace(5) = 'X'; // assign X to space after Hello
cout << s;
return 0;
}
char &replace(int i)
{
return s[i];
}
- A function may return a reference.
- This has the rather startling effect of allowing a function to be used on
the left side of an assignment statement.
C's Dynamic Allocation
struct node {
int data;
struct node *left;
struct node *right;
}
...
main()
{
struct node *p;
...
p = (struct node *) malloc (sizeof(struct node));
...
free(p);
...
}
- In C, dynamic memory allocation is achieved by using malloc() and
free().
C++'s Dynamic Allocation
#include <iostream.h>
#include <stdlib.h>
main()
{
int *p;
p = new int (87); // initialize to 87
if (!p) {
cout << "Allocation error\n";
exit(1);
}
cout << "At " << p << " ";
cout << "is the value " << *p << "\n";
delete p;
return 0;
}
Allocating Objects
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
class balance {
double cur_bal;
char name[80];
public:
void set(double n, char *s) {
cur_bal = n;
strcpy(name, s);
}
void get_bal(double &n, char *s) {
n = cur_bal;
strcpy (s, name);
}
};
|
|
main()
{
balance *p;
char s[80];
double n;
p = new balance;
if (!p) {
cout << "Allocation error\n";
exit(1);
}
p->set(12387.87, "Ralph Wilson");
p->get_bal(n, s);
cout << s << "'s balance is: " << n;
cout << "\n";
delete p;
return 0;
}
|
- You can allocate objects dynamically by using new.
- When an object is created (using new), its constructor function
(if it has one) is called.
- When the object is freed, its destructor function is called.
- You can allocate arrays of objects. However, since no array allocated by
new can have an initializer, you must sure that a parameterless
constructor is provided with the class declaration.
End of Tutorial III
|