zoukankan      html  css  js  c++  java
  • C++ Primer Plus读书笔记06

    2012-03-04

    1、重载运算符 例如Time类重载+

           Time operator +(const Time input)

    {

      Time sum;

      sum.minute=input.minute+minute;;…

      return sum;

    }

    Time Sum(const Time &t)

    {

      ….

      return sum

    }

    两者功能一样,但左边是重载,可以实现Time a,b,c,d; a=b+c+d;这样的操作

    重载后的操作符至少有一个是用户定义的类型(本例为time型),且优先级不变。∴不可重载+表示(double-double)

           不可重载的操作符:sizeof,逗号,作用域运算符::,见P342

           另外,=,[],(),→只能通过成员函数进行重载

    (以上例子都是通过成员函数进行重载)

    eg.重载*,表示一个时间*n倍

           Time operator * (const int n){……}

    问题:Time A,B;   int n;   A=B*n等价于A=B.operator*(n) 

           但A=n*B就会出错      左侧的运算符是调用对象    引出友元

    2、友元:非成员函数进行重载

    Time operator *(int n,const Time &t)

    {      Time result;

           result.minute=t.minute*n;……

           return result;

    }此函数可实现A=n*B,但此函数不可访问t.minute等私有成员

    ∴引入友元~将原型放在类声明中,并加friend(实现在,cpp中)

    如friend Time operator *(int n,const Time &t);

    友元不是成员函数,∴不可Time::operator这样调用,但可访问私有数据

    3、常用的友元:重载<<

           应用场合:例如Time a,b;   cout<<a;

           若用成员函数重载,第一个操作数应该为Time 类,形如a<<cout,不易理解

    friend void operator << (iostream &os,const Time &t)

           {os<<t.hours<<t.minutes}

           //此函数是Time的友元,因为用到time.hours(private),但不是ostream的友元,os作为一个整体出现。∴不访问对象的私有成员便可以不是此类友元

           此时,cout<<a正常,但cout<<a<<b不正常;

           改正思路:使cout<<a变为一个ostream对象,所以更改变量为

    friend ostream& operator << (iostream &os,const Time &t)

           {……     return os;    }

     

    4、只有一个参数的构造函数可以以赋值形式初始化→用作自动类型转换

           Myclass test=10;相当于Myclass test=Myclass(10);

           可以用关键字explicit关闭这项特性  explicit Myclass(int n);

           则左边错,右边对

           类中的转换函数,将类类型转换为常见类型 见P368,P374

    5、class stringbad

    {

    char *str;       int len;    static int num_string;

    }//则类的每个对象都有一个自己的str,len,所有类对象共用一个num_string

    6、C++自动提供默认构造函数,复制构造函数,赋值运算符和默认析构函数

    复制构造函数举例:class test (copy);     class test=copy;   class test=class(copy)   class *test=new class (copy);//默认的复制构造函数为按值传递

    ∴复制的不是字符串,而是指向字符串的指针

    eg stringbad b=a;//则a.str与b.str指向同一处地址。对a析构后,b.str已经被释放 很危险。

    解决方案:使用显式构造函数进行深复制,复制str的副本,而非指针(默认为浅复制)

    实现:stringbad::stringbad(const stringbad &st)

    {

           len=st.len;     str=new char[str+1];    //深复制

           strncpy(str,st.str);

    }

    若类中包含使用new初始化的指针成员,则应定义一个复制构造函数,实现深复制(如上)   //默认构造函数是浅复制,只复制指针指

     

    赋值运算符会导致同样的问题

    stringbad a;   a=b;              //则a.str与b.str指向同一处地址

    解决方案:提供赋值操作符定义(与复制构造函数有3出区别)

    stringbad & stringbad::operator=(const stringbad &st)

    {

    if(this==&st)         return *this    //(1)函数应避免将对象赋给自身 否则对象重新赋值前,可能会删除对象的内容,参见(2

    delete [] str;         //(2)由于目标对象可能引用了以前分配的数据∴应释放

    len=st.len; str=new char [len+1];      strncpy(str,st.str);

    return *this           //(3)返回调用对象的引用,可以实现a=b=c=d这样的操作

    }      详见P389

  • 相关阅读:
    移动端跨平台方案对比:React Native、weex、Flutter
    js json处理 双引号
    jquery 发get post请求
    librtmp编译for android and ios 不要openssl
    mysql reset password重置密码
    pdf ppt word office转图片 教学白板
    使用阻塞队列实现生产者-消费者模型
    ThreadPoolExecutor线程池的分析和使用
    HashMap HashTable和ConcurrentHashMap的区别
    HTTP协议GET和POST请求的区别
  • 原文地址:https://www.cnblogs.com/yangtianxing/p/2435020.html
Copyright © 2011-2022 走看看