📄 ch13_02.htm
字号:
<HTML><HEAD><TITLE>Recipe 13.1. Constructing an Object (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen & Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly & Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:42:15Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-243-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch13_01.htm"TITLE="13. Classes, Objects, and Ties"><LINKREL="prev"HREF="ch13_01.htm"TITLE="13.0. Introduction"><LINKREL="next"HREF="ch13_03.htm"TITLE="13.2. Destroying an Object"></HEAD><BODYBGCOLOR="#FFFFFF"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Perl Cookbook"><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><p><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch13_01.htm"TITLE="13.0. Introduction"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 13.0. Introduction"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch13_01.htm"TITLE="13. Classes, Objects, and Ties"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch13_03.htm"TITLE="13.2. Destroying an Object"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 13.2. Destroying an Object"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch13-25741">13.1. Constructing an Object</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-281">Problem<ACLASS="indexterm"NAME="ch13-idx-1000004463-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004463-1"></A></A></H3><PCLASS="para">You want to create a way for your users to generate new objects.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-287">Solution</A></H3><PCLASS="para">Make a constructor. In Perl, the constructor method must not only initialize its object, but must also first allocate memory for it, typically using an anonymous hash. C++ constructors, on the other hand, are called with memory already allocated. The rest of the object-oriented world would call C++'s constructors <EMCLASS="emphasis">initializers</EM><ACLASS="indexterm"NAME="ch13-idx-1000004483-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004483-1"></A>.</P><PCLASS="para">Here's the canonical object constructor in Perl:</P><PRECLASS="programlisting">sub new { my $class = shift; my $self = { }; bless($self, $class); return $self;} </PRE><PCLASS="para">This is the equivalent one-liner:</P><PRECLASS="programlisting">sub new { bless( { }, shift ) }</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-311">Discussion</A></H3><PCLASS="para">Any method that allocates and initializes a new object acts as a constructor. The most important thing to remember is that a reference isn't an object until <CODECLASS="literal">bless</CODE> has been called on it. The simplest possible constructor, although not particularly useful, is the following:</P><PRECLASS="programlisting">sub new { bless({}) }</PRE><PCLASS="para">Let's add some initialization:</P><PRECLASS="programlisting">sub new { my $self = { }; # allocate anonymous hash bless($self); # init two sample attributes/data members/fields $self->{START} = time(); $self->{AGE} = 0; return $self;} </PRE><PCLASS="para">This constructor isn't very useful because it uses the single-argument form of <CODECLASS="literal">bless</CODE>, which always blesses the object into <EMCLASS="emphasis">the current package</EM>. This means it can't be usefully inherited from; objects it constructs will always be blessed into the class that the <CODECLASS="literal">new</CODE> function was compiled into. In the case of inheritance, this is not necessarily the class on whose behalf the method was invoked.</P><PCLASS="para">To solve this, have the constructor heed its first argument. For a class method, this is the package name. Pass this class name as the second argument to <CODECLASS="literal">bless</CODE>:</P><PRECLASS="programlisting">sub new { my $classname = shift; # What class are we constructing? my $self = {}; # Allocate new memory bless($self, $classname); # Mark it of the right type $self->{START} = <CODECLASS="literal">time();</CODE> # init data fields $self->{AGE} = <CODECLASS="literal">0;</CODE> return $self; # And give it back} </PRE><PCLASS="para">Now the constructor can be correctly inherited by a derived class.</P><PCLASS="para">You might also want to separate the memory allocation and blessing step from the instance data initialization step. Simple classes won't need this, but it makes inheritance easier; see <ACLASS="xref"HREF="ch13_11.htm"TITLE="Accessing Overridden Methods">Recipe 13.10</A>.</P><PRECLASS="programlisting">sub new { my $classname = shift; # What class are we constructing? my $self = {}; # Allocate new memory bless($self, $classname); # Mark it of the right type $self->_init(@_); # Call _init with remaining args return $self;} # "private" method to initialize fields. It always sets START to# the current time, and AGE to 0. If called with arguments, _init# interprets them as key+value pairs to initialize the object with.sub _init { my $self = shift; $self->{START} = <CODECLASS="literal">time();</CODE> $self->{AGE} = 0; if (@_) { my %extra = @_; @$self{keys %extra} = values %extra; } } <ACLASS="indexterm"NAME="ch13-idx-1000004479-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004479-1"></A><ACLASS="indexterm"NAME="ch13-idx-1000004479-2"></A></PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-1000004330">See Also</A></H3><PCLASS="para"><ICLASS="filename">perltoot </I>(1) and <ICLASS="filename">perlobj </I>(1); <ACLASS="olink"HREF="../prog/ch05_01.htm">Chapter 5</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A>; <ACLASS="xref"HREF="ch13_07.htm"TITLE="Cloning Objects">Recipe 13.6</A>; <ACLASS="xref"HREF="ch13_10.htm"TITLE="Writing an Inheritable Class">Recipe 13.9</A>; <ACLASS="xref"HREF="ch13_11.htm"TITLE="Accessing Overridden Methods">Recipe 13.10</A></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch13_01.htm"TITLE="13.0. Introduction"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 13.0. Introduction"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch13_03.htm"TITLE="13.2. Destroying an Object"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 13.2. Destroying an Object"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">13.0. Introduction</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">13.2. Destroying an Object</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <a href="copyrght.htm">Copyright © 2002</a> O'Reilly & Associates. All rights reserved.</font> </p> <map name="library-map"> <area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map> </BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -