📄 tut4-3.html
字号:
<P>
The <TT><B>protected</B></TT> specifier is similar to <TT><B>private</B></TT>,
its only difference occurs when deriving classes. When we derive a class,
<TT><B>protected</B></TT> members of the base class can be used by other members of
the derived class, nevertheless <TT><B>private</B></TT> member cannot.
Since we wanted <TT><B>width</B></TT> and <TT><B>height</B></TT> to
have the ability to be manipulated by members of the derived classes
<TT><B>CRectangle</B></TT> and <TT><B>CTriangle</B></TT> and not only by members of
<TT><B>CPolygon</B></TT>, we have used <TT><B>protected</B></TT> access instead of
<TT><B>private</B></TT>.
<P>
We can summarize the different access types according to whom can access them
in the following way:
<blockquote >
<TABLE BORDER=1>
<TR><TD BGCOLOR="silver" ALIGN="center"><B>Access</B></TD>
<TD BGCOLOR="silver" ALIGN="center"><TT>public</TT></TD>
<TD BGCOLOR="silver" ALIGN="center"><TT>protected</TT></TD>
<TD BGCOLOR="silver" ALIGN="center"><TT>private</TT></TD></TR>
<TR><TD BGCOLOR="silver">members of the same class</TD>
<TD ALIGN="center">yes</TD>
<TD ALIGN="center">yes</TD>
<TD ALIGN="center">yes</TD></TR>
<TR><TD BGCOLOR="silver">members of derived classes</TD>
<TD ALIGN="center">yes</TD>
<TD ALIGN="center">yes</TD>
<TD ALIGN="center"><FONT COLOR="red">no</FONT></TD></TR>
<TR><TD BGCOLOR="silver">not-members</TD>
<TD ALIGN="center">yes</TD>
<TD ALIGN="center"><FONT COLOR="red">no</FONT></TD>
<TD ALIGN="center"><FONT COLOR="red">no</FONT></TD></TR>
</TABLE></BLOCKQUOTE>
where "<I>not-members</I>" represent any reference from outside the class,
such as from <TT><B>main()</B></TT>, from another class or from any function,
either global or local.
<P>
In our example, the members inherited by <TT><B>CRectangle</B></TT> and
<TT><B>CTriangle</B></TT> follow with the same access permission as in the base class
<TT><B>CPolygon</B></TT>:
<blockquote ><PRE>
<TT>CPolygon::width</TT> <FONT COLOR="green"><I>// protected access</I></FONT>
<TT>CRectangle::width</TT> <FONT COLOR="green"><I>// protected access</I></FONT>
<TT>CPolygon::set_values()</TT> <FONT COLOR="green"><I>// public access</I></FONT>
<TT>CRectangle::set_values()</TT> <FONT COLOR="green"><I>// public access</I></FONT>
</PRE></BLOCKQUOTE>
This is because we have derived a class from the other as <TT><B>public</B></TT>, remember:
<blockquote ><TT>class CRectangle: <B>public</B> CPolygon;</TT></BLOCKQUOTE>
this <TT><B>public</B></TT> keyword represents the <U>minimum</U> level of protection that
the inherited members of the base class (<TT><B>CPolygon</B></TT>)
must acquire in the new class (<TT><B>CRectangle</B></TT>). The minimum access level
for the inherited members can be changed by specifying <TT><B>protected</B></TT> or
<TT><B>private</B></TT> instead of <TT><B>public</B></TT>. For example,
<TT><B>daughter</B></TT> is a class derived from <TT><B>mother</B></TT> that we defined
thus:
<blockquote ><TT>class daughter: protected mother;</TT></BLOCKQUOTE>
this would establish <TT><B>protected</B></TT> as the minimum access level for the members
of <TT><B>daughter</B></TT> that it inherited from <TT><B>mother</B></TT>.
That is, all members that were <TT><B>public</B></TT> in <TT><B>mother</B></TT>
would become <TT><B>protected</B></TT> in <TT><B>daughter</B></TT>, that would be the
minimum level at which they can be inherited. Of course, this would not restrict that
<TT><B>daughter</B></TT> could have its own <TT><B>public</B></TT> members.
The minimum level would only be established for the inherited members of
<TT><B>mother</B></TT>.
<P>
The most common use of an inheritance level different from <TT><B>public</B></TT> is
<TT><B>private</B></TT> that serves to completely encapsulate the base class,
since, in that case, nobody except its own class will be able to access the members
of the base class from which it is derived. Anyway, in most cases classes are
derived as <TT><B>public</B></TT>.
<P>
If no access level is explicitly written <TT><B>private</B></TT> is assumed for classes
created with the <TT><B>class</B></TT> keyword and <TT><B>public</B></TT> for those created
with <TT><B>struct</B></TT>.
<P>
<H2>What is inherited from the base class?</H2>
In principle every member of a base class is inherited by a derived class except:<BR>
<UL>
<LI><B>Constructor and destructor</B>
<LI><B><TT>operator=()</TT> member</B>
<LI><B>friends</B>
</UL>
Although the constructor and destructor of the base class are not inherited,
the default constructor (i.e. constructor with no parameters) and the destructor
of the base class are always called when a new object of a
derived class is created or destroyed.
<P>
If the base class has no default constructor or
you want that an overloaded constructor is called when a new derived object
is created, you can specify it in
each constructor definition of the derived class:
<BLOCKQUOTE><TT>
derived_class_name (parameters) : base_class_name (parameters) {}
</TT></BLOCKQUOTE>
For example:
<P>
<CENTER>
<TABLE WIDTH=100% CELLPADDING=5 CELLSPACING=5><TR><TD BGCOLOR="#FFFFBF" WIDTH=50% VALIGN="top">
<TT><PRE><I>// constructors and derivated classes</I>
#include <iostream.h>
class mother {
public:
mother ()
{ cout << "mother: no parameters\n"; }
mother (int a)
{ cout << "mother: int parameter\n"; }
};
class daughter : public mother {
public:
daughter (int a)
{ cout << "daughter: int parameter\n\n"; }
};
class son : public mother {
public:
son (int a) : mother (a)
{ cout << "son: int parameter\n\n"; }
};
int main () {
daughter cynthia (1);
son daniel(1);
return 0;
}
</PRE></TT>
</TD><TD BGCOLOR="silver" WIDTH=50% VALIGN="top"><TT>
<B>mother: no parameters<BR>
daughter: int parameter<BR>
<BR>
mother: int parameter<BR>
son: int parameter<BR>
</B>
</TT></TD></TR></TABLE>
</CENTER>
<P>
Observe the difference between which mother's constructor is called when
a new <TT><B>daughter</B></TT> object is created and which when it is
a <TT><B>son</B></TT> object. The difference is because the constructor
declaration of <TT><B>daughter</B></TT> and <TT><B>son</B></TT>:
<BLOCKQUOTE><TT><PRE>
daughter (int a) <I>// nothing specified: call default constructor</I>
son (int a) : mother (a) <I>// constructor specified: call this one</I>
</PRE></TT></BLOCKQUOTE>
<P>
<H2>Multiple inheritance</H2>
In C++ it is perfectly possible that a class inherits fields and methods from more than
one class simply by separating the different base classes with commas in the declaration
of the derived class. For example, if we had a specific class to print on screen
(<TT><B>COutput</B></TT>) and we wanted that our classes <TT><B>CRectangle</B></TT> and
<TT><B>CTriangle</B></TT> also inherit its members in addition to those of
<TT><B>CPolygon</B></TT> we could write:
<blockquote ><TT>
class CRectangle: public CPolygon, public COutput {<BR>
class CTriangle: public CPolygon, public COutput {
</TT></BLOCKQUOTE>
here is the complete example:
<P>
<CENTER>
<TABLE WIDTH=100% CELLPADDING=5 CELLSPACING=5><TR><TD BGCOLOR="#FFFFBF" WIDTH=50% VALIGN="top">
<TT><PRE><I>// multiple inheritance</I>
#include <iostream.h>
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b;}
};
class COutput {
public:
void output (int i);
};
void COutput::output (int i) {
cout << i << endl;
}
class CRectangle: public CPolygon, public COutput {
public:
int area (void)
{ return (width * height); }
};
class CTriangle: public CPolygon, public COutput {
public:
int area (void)
{ return (width * height / 2); }
};
int main () {
CRectangle rect;
CTriangle trgl;
rect.set_values (4,5);
trgl.set_values (4,5);
rect.output (rect.area());
trgl.output (trgl.area());
return 0;
}
</PRE></TT>
</TD><TD BGCOLOR="silver" WIDTH=50% VALIGN="top"><TT>
<B>20<BR>10</B>
</TT></TD></TR></TABLE>
</CENTER>
<!--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="tut4-2.html">
<IMG SRC="butnback.gif" ALIGN="right" BORDER=0>
Previous:<BR><B>4-2. Overloading operators. this. Static members.</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-4.html">
<IMG SRC="butnnext.gif" ALIGN="left" BORDER=0>
Next:<BR><B>4-4. Virtual members. Abstraction. Polymorphism.</B></A>
</TD></TR></TABLE>
</CENTER>
<!--/cuatut-->
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -