static data member
static member functions
For operating on private, static data members!
class X {
private:
static int Z; // static data member
}
int X::Z = 0; // initialize
Add a public member function to operate on Z:
class X {
private:
static int Z; // static data member
public:
static void incrZ();
}
int X::Z = 0; // initialize
And, outside the class, use this function:
X::incrZ();
Remember, there is only 1 Z for all
X objects. . .so, a static function
is not invoked on a particular object.
static member function (private)
Not invoked on an object.
Therefore, no this pointer!
And, can only access static
data members!
For use when the member function is only to be used within the class.
Example: We have a linked list Node
structures. To implement a function that frees up
the space taken by this linked list, use
a private, static function:
private:
static void freeList(Node *L); // declaration
Use:
List::~List() { // destructor
freeList(head);
}
Both the destructor (shown here) and the overloaded assignment operator (not shown) would use this function. The overloaded assignment operator uses this function to properly do memory management on the LHS object.
operator overloading
Webster dictionary definition:
polymorphic - having, assuming, or occurring
in various forms, characters, or styles
+
-
*
!
<
&&
<<
etc.)
work on class objects
The overloaded operator is implemented
with a function
(an operator function)
Overloaded operator prototype:
returntype operatorop( );where op is replaced by the operator's symbol.
(from Polynomial class)
Prototype
for an overloaded assignment operator:
const Polynomial & operator=(const Polynomial & rhs);
Using the overloaded assignment operator:
p1 = p2;
p1.operator=(p2);
The operator=() operator function within
the Polynomial class is invoked,
because p1 is a Polynomial
class object.
With code such as
ob2 = ob1;
this operator=() function must
ob1 = ob1;
ob2 memory
ob1
Limitations:
sizeof . .* :: ?:
operator**()
for exponentiation, since ** is not an operator.
= () [] ->
Advice:
Use overloaded operator functions to
do something suggested by the operator!
If you saw this code:
flag = (ob2 && ob1);the overloaded operator should do a logical and.
If it instead swapped two unequal objects,
and returned a boolean indicating that the swap occurred,
yuck!
The alternative? Define a function!
boolean swap_if_not_equal( );
A problem solved by making friends.
Suppose we want to do multiplication of a
matrix object by a double.
A = B * 12.6;
Define operator*() for matrices,
and the compiler generates the call
A = B.operator*(12.6); // works well
But, reverse the order of the operands:
A = 12.6 * B;
and the compiler cannot generate a call
to the member function operator*()
A = 12.6.operator*(B); // nasty!
One possible solution:
Define an operator*() function that handles
this particular case
A = 12.6 * B;
The additional operator*() definition
Matrix operator*(double x, Matrix m) {
return (m * x);
}
Note: This is not a Matrix member function!
Member function (not static)
is invoked on an object.
The call appears as
obj.fcn( )
Nonmember function
is not invoked on an object.
The call appears as
fcn( )
Friends also solve the problem.
They can be
A friend describes access control to a class.
A friend has the same access priviledges
as a member function.
A friend can access private data members.
The friend function
It is a nonmember function.
Its declaration (prototype) goes in the class declaration!
Placed before the public or private keyword
is fine.
The keyword friend is added.
friend Matrix operator*(double x, Matrix & m);
Place the friend function definition with the other class definitions.
The definition does not use Matrix::,
and
does not use the keyword friend.
Matrix operator*(double x, Matrix & m) {
// may access private data members of m
}
Note:
Ask 10 different C++ programmers to
write a specific program in C++, and
you will likely get 6 dramatically different
programs.
What could be different?
Look at the Polynomial code example.
It was written by Hasti and Skrentny.
Karen would have produced a different
implemention.
However, it provides lots of excellent
discussion points!
overloading << for cout
Consider the following code:
int x = 3; int y = 5; cout << "x=" << x << " y=" << y << endl;
The output appears
------------------ |x=3 y=5 | |^
cout is an ostream class object,
and the << operator is overloaded.
The << operator is evaluated left-to-right.
First step:
(cout << "x=") << x . . .
This prints x=, and
returns a reference to cout
Second step is then
(cout << x) << " y=" . . .
This prints the value of x, and
returns a reference to cout
The Polynomial implementation
for the overloaded << operator:
Declaration of nonmember function:
ostream & operator<<(ostream & out, const Polynomial & p);
Definition:
ostream & operator<<(ostream & out, const Polynomial & p) {
p.print(out); // calls member function
return out;
}
An alternative Polynomial implementation
for the overloaded << operator.
Make it a friend function.
Declaration:
friend ostream & operator<<(ostream & out, const Polynomial & p);
Definition:
ostream & operator<<(ostream & os, const Polynomial & p) {
if (size == 0)
return os;
for (int i= . . .
os << coefs[i] << "x^" << . . .
return os;
}
friend function can access private data members
uses overloaded << on cout, giving it primitive types
| Copyright © Karen Miller, 2007 |