⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ei9.htm

📁 一个非常适合初学者入门的有关c++的文档
💻 HTM
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN" "http://www.w3.org/TR/REC-html40/frameset.dtd">
<HTML LANG="EN">
<HEAD>
<title>Effective C++, 2E | Item 9: Avoid hiding the "normal" form of new.</TITLE>
<LINK REL=STYLESHEET HREF=../INTRO/ECMEC.CSS>

<SCRIPT LANGUAGE="Javascript" SRC="../JAVA/COOKIE.JS"></SCRIPT>
<SCRIPT LANGUAGE="Javascript">var imagemax = 0; setCurrentMax(0);</SCRIPT>
<SCRIPT LANGUAGE="Javascript" SRC="../JAVA/DINGBATS.JS"></SCRIPT>
<SCRIPT LANGUAGE="Javascript">
var dingbase = "EI9_DIR.HTM";
var dingtext = "Item E9, P";
if (self == top) {top.location.replace(dingbase + this.location.hash);}
</SCRIPT>

</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" ONLOAD="setResize()">
<!-- SectionName="E9: Avoid hiding the 'normal' form of new." -->
<A NAME="1961"></A>
<DIV ALIGN="CENTER"><FONT SIZE="-1">Back to <A HREF="EI8_FR.HTM" TARGET="_top">Item 8: Adhere to convention when writing operator new and operator delete.</A> &nbsp;&nbsp;<BR>&nbsp;&nbsp;Continue to <A HREF="EI10_FR.HTM" TARGET="_top">Item 10: Write operator delete if you write operator new.</A></FONT></DIV>

<P><A NAME="dingp1"></A><FONT ID="eititle">Item 9: &nbsp;Avoid hiding the "normal" form of <CODE>new</CODE>.</FONT><SCRIPT>create_link(1);</SCRIPT>
</P>

<A NAME="1962"></A>
<P><A NAME="dingp2"></A>
A declaration of a name in an inner scope hides the same name in outer scopes, so for a function <CODE>f</CODE> at both global and class scope, the member function will hide the global <NOBR>function:<SCRIPT>create_link(2);</SCRIPT>
</NOBR></P>
<A NAME="61573"></A>
<UL><PRE><A NAME="p38"></A>
void f();                             // global function
</PRE>
</UL><A NAME="61574"></A>
<UL><PRE>class X {
public:
  void f();                           // member function
};
</PRE>
</UL><A NAME="1965"></A>
<UL><PRE>X x;
</PRE>
</UL><A NAME="1966"></A>
<UL><PRE>
f();                                  // calls global f
</PRE>
</UL><A NAME="1967"></A>
<UL><PRE>
x.f();                                // calls X::f
</PRE>
</UL><A NAME="1968"></A>
<P><A NAME="dingp3"></A>
This is unsurprising and normally causes no confusion, because global and member functions are usually invoked using different syntactic forms. However, if you add to this class an <CODE>operator</CODE> <CODE>new</CODE> taking additional parameters, the result is likely to be an <NOBR>eye-opener:<SCRIPT>create_link(3);</SCRIPT>
</NOBR></P>
<A NAME="1970"></A>
<UL><PRE>class X {
public:
  void f();
</PRE>
</UL><A NAME="1971"></A>
<UL><PRE>  // operator new allowing specification of a
  // new-handling function
  static void * operator new(size_t size, new_handler p);
};
</PRE>
</UL><A NAME="1972"></A>
<UL><PRE>
void specialErrorHandler();          // definition is elsewhere
</PRE>
</UL><A NAME="1973"></A>
<UL><PRE>X *px1 =
  new (specialErrorHandler) X;       // calls X::operator new
</PRE>
</UL><A NAME="1974"></A>
<UL><PRE>
X *px2 = new X;                      // error!
</PRE>
</UL><A NAME="1975"></A>
<P><A NAME="dingp4"></A>
By declaring a function called "operator new" inside the class, you inadvertently block access to the "normal" form of <CODE>new</CODE>. Why this is so is discussed in <A HREF="./EI50_FR.HTM#8569" TARGET="_top">Item 50</A>. Here we're more interested in figuring out how to avoid the <NOBR>problem.<SCRIPT>create_link(4);</SCRIPT>
</NOBR></P>
<A NAME="1979"></A>
<P><A NAME="dingp5"></A>
One solution is to write a class-specific <CODE>operator</CODE> <CODE>new</CODE> that supports the "normal" invocation form. If it does the same thing as the global version, that can be efficiently and elegantly encapsulated as an inline <NOBR>function:<SCRIPT>create_link(5);</SCRIPT>
</NOBR></P>
<A NAME="1980"></A>
<UL><PRE>class X {
public:
  void f();
</PRE>
</UL><A NAME="1981"></A>
<UL><PRE>  static void * operator new(size_t size, new_handler p);
</PRE>
</UL><A NAME="1982"></A>
<UL><PRE>  static void * operator new(size_t size)
  { return ::operator new(size); }
};
</PRE>
</UL><A NAME="1983"></A>
<A NAME="p39"></A><UL><PRE>X *px1 =
  new (specialErrorHandler) X;      // calls X::operator
                                    // new(size_t, new_handler)
</PRE>
</UL><A NAME="1984"></A>
<UL><PRE>
X* px2 = new X;                     // calls X::operator
                                    // new(size_t)
</PRE>
</UL><A NAME="13809"></A>
<P><A NAME="dingp6"></A>
An alternative is to provide a default parameter value (see <A HREF="./EI24_FR.HTM#6250" TARGET="_top">Item 24</A>) for each additional parameter you add to <CODE>operator</CODE> <CODE>new</CODE>:<SCRIPT>create_link(6);</SCRIPT>
</P>
<A NAME="13819"></A>
<UL><PRE>class X {
public:
  void f();
</PRE>
</UL><A NAME="13820"></A>
<UL><PRE>  static
    void * operator new(size_t size,                // note default
                        new_handler p = 0);         // value for p
};
</PRE>
</UL><A NAME="13822"></A>
<UL><PRE>
X *px1 = new (specialErrorHandler) X;               // fine
</PRE>
</UL><A NAME="13836"></A>
<UL><PRE>X* px2 = new X;                                     // also fine
</PRE>
</UL><A NAME="1985"></A>
<P><A NAME="dingp7"></A>
Either way, if you later decide to customize the behavior of the "normal" form of <CODE>new</CODE>, all you need to do is rewrite the function; callers will get the customized behavior automatically when they <NOBR>relink.<SCRIPT>create_link(7);</SCRIPT>
</NOBR></P>

<DIV ALIGN="CENTER"><FONT SIZE="-1">Back to <A HREF="EI8_FR.HTM" TARGET="_top">Item 8: Adhere to convention when writing operator new and operator delete.</A> &nbsp;&nbsp;<BR>&nbsp;&nbsp;Continue to <A HREF="EI10_FR.HTM" TARGET="_top">Item 10: Write operator delete if you write operator new.</A></FONT></DIV>

</BODY>
</HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -