📄 tut4-1.html
字号:
are passed to the constructor at the moment at which the instances of the class are
created:
<blockquote ><TT>
CRectangle rect (3,4);<BR>
CRectangle rectb (5,6);
</TT></BLOCKQUOTE>
You can also see how neither the prototype nor the later constructor declaration
includes a return value, not even <TT><B>void</B></TT> type. This must always be thus.
A constructor never returns a value nor does the <TT><B>void</B></TT> have to be specified,
as we have shown in the previous example.
<P>
The <B>Destructor</B> fulfills the opposite functionality. It
is automatically called when an object is released from the memory, either because its
scope of existence has finished (for example, if it was defined as a local object
within a function and the function ends) or because it is an object dynamically assigned
and it is released using operator <TT><B>delete</B></TT>.
<P>
The destructor must have the same name as the class with a tilde (<TT><B>~</B></TT>)
as prefix and it must return no value.
<P>
The use of destructors is specially suitable when an object assigns dynamic memory
during its life and at the moment of being destroyed we want to release the memory
that it has used.
<P>
<CENTER>
<TABLE WIDTH=100% CELLPADDING=5 CELLSPACING=5><TR><TD BGCOLOR="#FFFFBF" WIDTH=50% VALIGN="top">
<TT><PRE><I>// example on constructors and destructors</I>
#include <iostream.h>
class CRectangle {
int *width, *height;
public:
CRectangle (int,int);
~CRectangle ();
int area (void) {return (*width * *height);}
};
CRectangle::CRectangle (int a, int b) {
width = new int;
height = new int;
*width = a;
*height = b;
}
CRectangle::~CRectangle () {
delete width;
delete height;
}
int main () {
CRectangle rect (3,4), rectb (5,6);
cout << "rect area: " << rect.area() << endl;
cout << "rectb area: " << rectb.area() << endl;
return 0;
}
</PRE></TT>
</TD><TD BGCOLOR="silver" WIDTH=50% VALIGN="top"><TT>
<B>rect area: 12<BR>rectb area: 30</B>
</TT></TD></TR></TABLE>
</CENTER>
<P>
<H2>Overloading Constructors</H2>
<P>
Like any other function, a constructor can also be overloaded with several functions
that have the same name but different types or numbers of parameters. Remember that the
compiler will execute the one that matches at the moment at which a function with that
name is called (<A HREF="tut2-3.html">Section 2.3, Functions-II</A>). In this case, at the
moment at which a class object is declared.
<P>
In fact, in the cases where we declare a class and we do not specify any constructor
the compiler automatically assumes two overloaded constructors
("<I>default constructor</I>" and "<I>copy constructor</I>"). For example, for the class:
<BLOCKQUOTE><TT><PRE>
class CExample {
public:
int a,b,c;
void multiply (int n, int m) { a=n; b=m; c=a*b; };
};
</PRE></TT></BLOCKQUOTE>
with no constructors, the compiler automatically assumes that it has the following
constructor member functions:
<UL>
<LI><B>Empty constructor</B><BR>
It is a constructor with no parameters defined as <I><B>nop</B></I> (empty block of
instructions). It does nothing.
<BLOCKQUOTE><TT>CExample::CExample () { };</TT></BLOCKQUOTE>
<LI><B>Copy constructor</B><BR>
It is a constructor with only one parameter of its same type
that assigns to every nonstatic class member variable of the object a copy of the
passed object.
<BLOCKQUOTE><TT><PRE>
CExample::CExample (const CExample& rv) {
a=rv.a; b=rv.b; c=rv.c;
}
</PRE></TT></BLOCKQUOTE>
</UL>
<P>It is important to realize that both default constructors: the <I>empty construction</I>
and the <I>copy constructor</I> exist only if no other constructor is explicitly declared.
In case that <U>any</U> constructor with <U>any</U> number of parameters is declared, none
of these two default constructors will exist. So if you want them to be there, you must
define your own ones.
<P>
Of course, you can also overload the class constructor providing different
constructors for when you pass parameters between parenthesis
and when you do not (empty):
<P>
<CENTER>
<TABLE WIDTH=100% CELLPADDING=5 CELLSPACING=5><TR><TD BGCOLOR="#FFFFBF" WIDTH=50% VALIGN="top">
<TT><PRE><I>// overloading class constructors</I>
#include <iostream.h>
class CRectangle {
int width, height;
public:
CRectangle ();
CRectangle (int,int);
int area (void) {return (width*height);}
};
CRectangle::CRectangle () {
width = 5;
height = 5;
}
CRectangle::CRectangle (int a, int b) {
width = a;
height = b;
}
int main () {
CRectangle rect (3,4);
CRectangle rectb;
cout << "rect area: " << rect.area() << endl;
cout << "rectb area: " << rectb.area() << endl;
}
</PRE></TT>
</TD><TD BGCOLOR="silver" WIDTH=50% VALIGN="top"><TT>
<B>rect area: 12<BR>rectb area: 25</B>
</TT></TD></TR></TABLE>
</CENTER>
<P>
In this case <TT><B>rectb</B></TT> was declared without parameters, so it
has been initialized with the <I>constructor</I> that has no parameters, which declares
both <TT><B>width</B></TT> and <TT><B>height</B></TT> with a value of <TT><B>5</B></TT>.
<P>
Notice that if we declare a new object and we do not want to pass parameters to it
we do not include parentheses <TT><B>()</B></TT>:
<BLOCKQUOTE><TT><PRE>
CRectangle rectb; <I>// right</I>
<FONT COLOR="red">CRectangle rectb(); <I>// wrong!</I></FONT>
</PRE></TT></BLOCKQUOTE>
<P>
<H2>Pointers to classes</H2>
It is perfectly valid to create pointers pointing to classes, in order to do that
we must simply consider that once declared, the class becomes a valid type,
so use the <I>class name</I> as the type for the pointer.
For example:
<blockquote><TT>CRectangle * prect;</TT></BLOCKQUOTE>
is a pointer to an object of class <TT><B>CRectangle</B></TT>.
<P>
As it happens with data structures, to refer directly to a member of an object pointed
by a pointer you should use operator <TT><B>-></B></TT>. Here is an example with
some possible combinations:
<P>
<CENTER>
<TABLE WIDTH=100% CELLPADDING=5 CELLSPACING=5><TR><TD BGCOLOR="#FFFFBF" WIDTH=50% VALIGN="top">
<TT><PRE><I>// pointer to classes example</I>
#include <iostream.h>
class CRectangle {
int width, height;
public:
void set_values (int, int);
int area (void) {return (width * height);}
};
void CRectangle::set_values (int a, int b) {
width = a;
height = b;
}
int main () {
CRectangle a, *b, *c;
CRectangle * d = new CRectangle[2];
b= new CRectangle;
c= &a;
a.set_values (1,2);
b->set_values (3,4);
d->set_values (5,6);
d[1].set_values (7,8);
cout << "a area: " << a.area() << endl;
cout << "*b area: " << b->area() << endl;
cout << "*c area: " << c->area() << endl;
cout << "d[0] area: " << d[0].area() << endl;
cout << "d[1] area: " << d[1].area() << endl;
return 0;
}
</PRE></TT>
</TD><TD BGCOLOR="silver" WIDTH=50% VALIGN="top"><TT>
<B>a area: 2<BR>*b area: 12<BR>*c area: 2<BR>d[0] area: 30<BR>d[1] area: 56</B>
</TT></TD></TR></TABLE>
</CENTER>
<P>
Next you have a summary on how can you read some pointer and class operators
(<TT><B>*, &, ., ->, [ ]</B></TT>) that appear in the previous example:
<blockquote><PRE>
<TT><B>*x</B></TT> <I>can be read:</I> pointed by <TT><B>x</B></TT>
<TT><B>&x</B></TT> <I>can be read:</I> address of <TT><B>x</B></TT>
<TT><B>x.y</B></TT> <I>can be read:</I> member <TT><B>y</B></TT> of object <TT><B>x</B></TT>
<TT><B>(*x).y</B></TT> <I>can be read:</I> member <TT><B>y</B></TT> of object pointed by <TT><B>x</B></TT>
<TT><B>x->y</B></TT> <I>can be read:</I> member <TT><B>y</B></TT> of object pointed by <TT><B>x</B></TT> (equivalent to the previous one)
<TT><B>x[0]</B></TT> <I>can be read:</I> first object pointed by <TT><B>x</B></TT>
<TT><B>x[1]</B></TT> <I>can be read:</I> second object pointed by <TT><B>x</B></TT>
<TT><B>x[n]</B></TT> <I>can be read:</I> (n+1)<SUP><SMALL>th</SMALL></SUP> object pointed by <TT><B>x</B></TT>
</PRE></BLOCKQUOTE>
Be sure you understand the logic of all of these before going on. If you have doubts,
read again this section and/or consult sections
"<A HREF="tut3-3.html">3.3, Pointers</A>" and
"<A HREF="tut3-5.html">3.5, Structures</A>".
<P>
<H2>Classes defined with keyword <TT>struct</TT></H2>
C++ language has extended the C keyword <TT><B>struct</B></TT> to the same functionality
of the C++ <TT><B>class</B></TT> keyword except that its members are <TT><B>public</B></TT>
by default instead of being <TT><B>private</B></TT>.
<P>
Anyway, because both <TT><B>class</B></TT> and <TT><B>struct</B></TT> have almost the
same functionality in C++, <TT><B>struct</B></TT> is usually used for
data-only structures and <TT><B>class</B></TT> for
classes that have procedures and member functions.
<!--cuatut-->
<P>
<CENTER><TABLE WIDTH=100% CELLPADDING=0 CELLSPACING=0 BORDER=0>
<TR><TD BGCOLOR="#0000FF"><IMG SRC="head0.gif" WIDTH=2 HEIGHT=2></TD></TR>
<TR><TD ALIGN="right"><FONT FACE="arial,helvetica" SIZE=1>© The C++ Resources Network, 2000-2003 - All rights reserved</FONT></TD></TR>
</TABLE></CENTER>
<P>
<CENTER>
<TABLE CELLPADDING=0 WIDTH=100%>
<TR><TD ALIGN="right" WIDTH=45%><A HREF="tut3-6.html">
<IMG SRC="butnback.gif" ALIGN="right" BORDER=0>
Previous:<BR><B>3-6. User defined data types.</B></A></TD>
<TD ALIGN="center" WIDTH=10%><A HREF="index.html">
<IMG SRC="butnindx.gif" BORDER=0><BR>
index</A></TD>
<TD ALIGN="left" WIDTH=45%><A HREF="tut4-2.html">
<IMG SRC="butnnext.gif" ALIGN="left" BORDER=0>
Next:<BR><B>4-2. Overloading operators. this. Static members.</B></A>
</TD></TR></TABLE>
</CENTER>
<!--/cuatut-->
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -