/**/ /*********************************************************************** * C++必知必会 条款12 * 赋值和初始化并不相同 * * 赋值发生在你赋值时,除此之外,遇到所有其它的复制情形均为初始化.包括声明、函数返 * 回、 参数传递以及捕获异常中的初始化.***********************************************************************/ int a = 12 ; // 初始化,将0x000c复制给a a = 12 ; // 赋值,将0x000c复制给a class String ... { private: char *s_; public: String(const char *init); String &operator = (const char *str); //... } ; // 初始化 String::String( const char * init) // 构造函数 ... { if(!init) init = ""; s_ = new char(strlen(init)+1); //注意这句,赋值里可没有.赋值会假定已经分配内存区域. strcpy(s_,init); } // 赋值 String & String:: operator = ( const char * str) ... { if(!str) str = ""; char *tmp = strcpy(new char[strlen(str)+1],str); delete[] s_; //类似于 析构 s_ = tmp; //类似于 构造 return *this; } /**/ /*********************************************************************** * 赋值有点像一个析构动作后跟了一个构造动作. * 目标左侧(this)在采用源(右侧,str)重新初始化之前,必须被清理掉. * 由于一个正当的赋值操作会清掉左边的实参,因此永远不要对一个未初始化的存储区执行 * 用户自定义的赋值操作.***********************************************************************/ String * names = static_cast < String *> (:: operator new (BUFSIZ)); names[ 0 ] = " Oh,wrong! " ; // 赋值 wrong /**/ /*********************************************************************** * 上例中,因为我们直接调用了operator new,避免了String默认构造函数执行隐式的初始 * 化,因此names此时指向一块随机们的内存.在执行赋值操作时,试图执行delete[]操作,出错!***********************************************************************/