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

📄 subject_49147.htm

📁 vc
💻 HTM
字号:
<p>
序号:49147 发表者:软体狂人 发表日期:2003-08-07 12:42:05
<br>主题:《C++ primer》书中的错误
<br>内容:《C++ primer》一书名气自然是大得不得了,可是我发现书中有一些低级的错误,如P617页中讲到了操作符=的某些不佳的实现方式,又在P618页中举出一个例子说明这种实现方式有什么坏处:<BR>char ia[]={'d','a','n','c','e','r'};<BR>String trap=ia;<BR>ia[3]='g';<BR><BR>这里的第二行代码是一个构造函数调用,而按作者的意思是操作符=的调用,这纯粹是误导!<BR><BR>高手们以为如何?
<br><a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p>
<hr size=1>
<blockquote><p>
回复者:老毒物 回复日期:2003-08-07 14:50:24
<br>内容:String trap=ia;<BR>第一步调用默认构造函数<BR>第二步调用=操作符<BR><BR>误导?
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:软体狂人 回复日期:2003-08-07 20:57:04
<br>内容:楼上说得根本不对,那里有什么=的调用嘛!
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:老毒物 回复日期:2003-08-07 21:02:26
<br>内容:把构造和=的代码写好<BR>单步调式看看
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:萧七 回复日期:2003-08-08 18:56:14
<br>内容:String trap=ia;<BR>先构造一个空的对象,再赋值<BR>string trap;<BR>trap=ia;
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:罗兹维尔 回复日期:2003-08-08 23:43:28
<br>内容:不是吧,调用的应该是拷贝构造函数
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:老毒物 回复日期:2003-08-09 02:38:07
<br>内容:String trap=ia;<BR>String trap2(trap); //这个才是构造函数<BR><BR><BR>还是那句话,把自定义类的函数定义好,自己单步调式试试<BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
<font color=red>答案被接受</font><br>回复者:罗兹维尔 回复日期:2003-08-10 16:21:12
<br>内容:我不知道老毒物自己有没有把自定义类的函数定义好,自己单步调式<BR><BR>现在有这样一个String的类如下,摘自"Rumination on C++"<BR>但是有一些修改<BR><BR>/*******main.cpp*************/<BR>#include "String.h"<BR>#include&lt;iostream&gt;<BR><BR>using namespace std;<BR><BR>int main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;String s = "hello world";<BR>&nbsp;&nbsp;&nbsp;&nbsp;return 0;<BR>}<BR><BR><BR><BR><BR><BR><BR><BR><BR>/***********String.h***************/<BR>class ostream;<BR>#include &lt;string.h&gt;<BR><BR>class String {<BR>&nbsp;&nbsp;&nbsp;&nbsp;friend int operator==(const String&amp; op1, const String&amp; op2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;friend int operator!=(const String&amp; op1, const String&amp; op2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;friend int operator&lt;(const String&amp; op1, const String&amp; op2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;friend int operator&gt;(const String&amp; op1, const String&amp; op2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;friend int operator&lt;=(const String&amp; op1, const String&amp; op2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;friend int operator&gt;=(const String&amp; op1, const String&amp; op2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;friend ostream&amp; operator&lt;&lt;(ostream&amp; os, const String&amp; s);<BR>public:<BR>&nbsp;&nbsp;&nbsp;&nbsp;String(): data(new char[1]), sz(0) { *data = 0; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;String(char* p) { assign(p, strlen(p)); }<BR>&nbsp;&nbsp;&nbsp;&nbsp;~String() { delete[] data; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;String(const String&amp; s) { assign(s.data, s.sz); }<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;int length() const { return sz; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;void make_cstring(char* p, int len) const <BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (sz &lt;= len)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcpy(p, data);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw("Not enough memory supplied");<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;operator char*() { return data; }<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;String&amp; operator=(const String&amp; s)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (this != &amp;s) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete [] data;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assign(s.data, s.sz);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return *this;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;String&amp; operator=(const char *s)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (s) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete [] data;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assign(s, strlen(s));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return *this;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;String&amp; String::operator+=(const String&amp; s);<BR>private:<BR>&nbsp;&nbsp;&nbsp;&nbsp;int sz;<BR>&nbsp;&nbsp;&nbsp;&nbsp;char* data;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;void assign(const char* s, unsigned len) <BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data = new char[len + 1];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (data == 0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw "out of memory";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sz = len;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcpy(data, s);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};<BR><BR>String operator+(const String&amp; op1, const String&amp; op2);<BR><BR><BR><BR><BR><BR><BR><BR><BR>/****************String.cpp****************/<BR>#include "String.h"<BR>#include &lt;iostream.h&gt;<BR>#include &lt;string.h&gt;<BR><BR>String&amp; String::operator+=(const String&amp; s) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;char* odata = data;<BR>&nbsp;&nbsp;&nbsp;&nbsp;assign(data, sz + s.sz + 1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;strcat(data, s.data);<BR>&nbsp;&nbsp;&nbsp;&nbsp;delete [] odata;<BR>&nbsp;&nbsp;&nbsp;&nbsp;return *this;<BR>}<BR><BR>String operator+(const String&amp; op1, const String&amp; op2) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;String ret(op1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;ret += op2;<BR>&nbsp;&nbsp;&nbsp;&nbsp;return ret;<BR>}<BR><BR>int operator==(const String&amp; op1, const String&amp; op2) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;return (strcmp(op1.data, op2.data) == 0);<BR>}<BR>int operator!=(const String&amp; op1, const String&amp; op2) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;return (strcmp(op1.data, op2.data) != 0);<BR>}<BR>int operator&lt;=(const String&amp; op1, const String&amp; op2) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;return (strcmp(op1.data, op2.data) &lt;= 0);<BR>}<BR>int operator&gt;=(const String&amp; op1, const String&amp; op2) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;return (strcmp(op1.data, op2.data) &gt;= 0);<BR>}<BR>int operator&lt;(const String&amp; op1, const String&amp; op2) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;return (strcmp(op1.data, op2.data) &lt; 0);<BR>}<BR>int operator&gt;(const String&amp; op1, const String&amp; op2) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;return (strcmp(op1.data, op2.data) &gt; 0);<BR>}<BR><BR>ostream&amp; operator&lt;&lt;(ostream&amp; os, const String&amp; s) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;return os &lt;&lt; s.data;<BR>}<BR><BR><BR>我重载了这样一个operator= <BR>String&amp; operator=(const char *s)<BR>注意有这样的拷贝构造函数<BR>String(const String&amp; s) { assign(s.data, s.sz); }<BR>如果将这拷贝构造函数注释了的话将会导致一个编译错误<BR>error C2440: 'initializing' : cannot convert from 'char [12]' to 'class String'<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;No constructor could take the source type, or constructor overload resolution was ambiguous<BR>如果这句没有被注释的话单部将会调用拷贝构造函数String(const String&amp; s)<BR><BR>如果老毒物是那种指点人一两句就可以使人醍醐灌顶的高手的话<BR>请你再次指点我一两句<BR>在下一定如沐春风<BR><BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:软体狂人 回复日期:2003-08-10 23:58:08
<br>内容:我本人的意见基本和罗兹维尔兄一样,<BR>string str=ia;<BR>其实应该和下面是一样的:<BR>string str(ia);<BR>就是对如下构造函数的调用:<BR>string&amp; string::string(const char*);<BR><BR>我真的不理解为什么老毒物兄如此坚持“单步调试”!
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:老毒物 回复日期:2003-08-11 00:27:47
<br>内容:经过代码、单步测试,发现,自己错了,老罗说得对。直接调用了拷贝构造函数。<BR><BR>我道歉并羞愧万分<BR><BR>汗颜ing
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:软体狂人 回复日期:2003-08-11 14:36:54
<br>内容:就我提到的那个问题而言,是调用了一个构造函数,但并不是拷贝构造函数,总而言之没有调用=操作符。<BR>大家对于《C++ primer》书中出现这样的误导错误有什么看法?
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:luotian 回复日期:2003-08-11 18:18:13
<br>内容:兄弟是一低低手,希望得到各位高手巨无情的指教,谢谢.<BR>如果IA的定义改成const char * ia= "something here"<BR>then <BR>string trap<BR>trap=ia<BR>应该是对操作符的重载吧.<BR><BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:罗兹维尔 回复日期:2003-08-11 22:38:37
<br>内容:Meyers的Effective C++把String::String(const char*);叫做copy constructor,我也就跟着叫了<BR><BR>C++ Primer没有我想象中那么好,但是很值得一读,估计Lippman写代码的时候没有考虑清楚,应该是误笔,要是说Lippman在程序语法认识上有错误的话是不可思议的,他连编译器都写过,还会连这个都不懂?<BR><BR>luotian,你这样的话就是调用operator = 了<BR><BR>老毒物,你的先调用缺省构造函数再调用operator =会在这样的情况下出现:<BR><BR>class test{<BR>public:<BR>test(){ str = "hello world"; }<BR>private:<BR>string str;<BR>}<BR><BR><BR>因为str没有在构造函数的初始化列表中初始化,而是在构造函数中对其赋值,所以str会先在初始化列表被初始化,这样就调用了缺省构造函数,而在构造函数中对str进行operator=<BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:gun_1981 回复日期:2003-08-11 22:55:00
<br>内容:原书上没有定义任何构造函数,包括拷贝构造函数.他只重载了"=",尽管这有问题.
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:软体狂人 回复日期:2003-08-11 23:16:38
<br>内容:罗兹维尔兄,你说Scott Meyers在Effective C++把String::String(const char*);叫做copy constructor了,在哪一页?可否告之小弟?果真如此的话,那要打Meyers的小屁股了!
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:张志民 回复日期:2003-08-13 18:08:27
<br>内容:具体的我不是很清楚,但是我觉得String trap=ia;<BR>这语句,string类型本身应该重载了=操作符,而且<BR>重载的这个函数应该是只调用string的拷贝构造函数,<BR><BR>我觉得自己有一些道理,但有些概念模糊,<BR>请各位执教!<BR><BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:罗兹维尔 回复日期:2003-08-13 22:14:02
<br>内容:页页都是
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:jinir 回复日期:2003-08-20 22:08:02
<br>内容:变量声明的时候有一套不同的机制而已,比如说<BR>int *p=0;<BR>难道是*p=0吗?<BR>单参数的类变量声明说是调用它的单参数构造函数<BR>string str=ia;<BR>就是<BR>string str=string(ia)的缩写.<BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>

⌨️ 快捷键说明

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