C++必知必会之(12)赋值和初始化并不相同

1、赋值发生于赋值时,除此之外,遇到的所有其他的复制情形均为初始化,包括声明、函数返回、参数传递以及捕获异常中的初始化。


对于内建类型来说,赋值和初始化的操作区别不明显,只是简单地复制一些位而已。

但对于用户自定义类型来说截然不同。考虑如下简单的非标准字符串类:

class String {

   public:

       String (const char *init );        //故意不标为explicit

       ~String( );

       String(const String &that);

       String  &operator = (const String &that);

       String  &operator = (const char *str);

       void    swap( String &that );

       friend   const   String   operator + ( const String &,  const String & );     //用于连接字符串

       friend bool operator < ( const String &,  const String & );

       //......

    private:

        String ( const char *,  const  char*);       //计算性的构造函数

        char *s_

};


2、采用字符串初始化一个string对象和简单,先分配一个足够大的缓冲区,用于容纳该字符串的复制,然后执行复制动作:

String::String ( const char *init )

{

    if( !init )   init = " ";

    s_ = new char [ strlen(init ) + 1];

    strcpy(s_,  init);

}


析构函数:  String::~String()   {  delete [ ]  s_ };


赋值比构造复杂一些:

String   &String::operator  =  ( const char *str)

{

    if( !str)    str = " ";

    char   *tmp = strcpy( new char[ strlen( str) + 1 ],  str);

    delete [ ] s_;

    s_ = tmp;

    return  *this;

}


3、对于String类型来说,String现有的字符缓冲区在被附加上一个新的字符缓冲区之前必须被释放掉。


由于一个正当的赋值操作会清掉左边的实参,因此永远都不应该对一个为初始化的存储区执行用户自定义赋值操作:

String  *names = statoc_cast<String *> (::operator new( BUFSIZ));

names[0] = "Sakamoto";    //delete[ ] 未被初始化的names!


names指向为初始化的存储区,因为我们调用了operator new,从而避免了通过String的默认构造函数执行的隐式初始化动作,因此names指向一块填充着随机位的内存。

  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值